{
  "openapi": "3.1.0",
  "info": {
    "title": "OGQ Partner API",
    "version": "1.0.0",
    "description": "OGQ IP Marketplace Partner API. 이 스펙에는 **파트너 키(`X-OGQ-API-KEY`)로 부르는 창구 전부**와 공개 상태 창구를 싣는다 — 라우트와 문서가 같은지 시험(`partner-openapi-contract.test.ts`)이 경로·메서드·인증·요청/응답 칸을 양쪽으로 맞댄다. This spec lists every endpoint called with a partner key (`X-OGQ-API-KEY`), plus public status endpoints. A contract test keeps paths, methods, authentication and request/response fields equal to the deployed routes. Endpoints outside `/api/v1` declare their own `servers` entry.",
    "contact": {
      "email": "dev@ogq.me"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://stg.nova.ogq.me/policies"
    }
  },
  "servers": [
    {
      "url": "https://stg.nova.ogq.me/api/v1",
      "description": "Staging (current)"
    }
  ],
  "components": {
    "securitySchemes": {
      "ogqUserSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "OID_AUT",
        "description": "Signed-in OGQ user session (OID cookie). Rova endpoints act only on the caller's own jobs."
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      },
      "partnerApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-OGQ-API-KEY",
        "description": "Partner API key issued by OGQ admin. Sent as a header on every partner request; the partner identity comes from the stored key row, never from the request."
      },
      "ogqAdminSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "OID_AUT",
        "description": "OGQ administrator session (OID cookie). Only for the admin path of mixed endpoints; partners use `partnerApiKey`."
      },
      "dspRequestProof": {
        "type": "apiKey",
        "in": "header",
        "name": "X-OGQ-DSP-Request-Proof",
        "description": "Request proof signed with an organization dataspace key (own consumer / approved counterparty). Used instead of a partner key on Dataspace Protocol endpoints."
      },
      "revalidationScopeToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Per-request scope token (`ogqrv_…`) issued when a partner opens a re-verification request and handed to the designated verifier. Valid for that one request for 7 days. Not a partner key."
      },
      "clearingPeerIdToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Peer clearing house credential (IDSA Clearing House W10). A DCP v1.0 self-issued ID token (JWT, EdDSA or ES256; iss = sub = the peer clearing house DID, aud = the platform DID, lifetime ≤ 10 minutes, jti used once) sent as `Authorization: Bearer <token>`. The peer DID must be on the allow list; its key is taken from the DID itself (`did:key`) or pinned on the list (`did:web`) — no DID document is fetched. Not available in production (empty allow list)."
      },
      "dcpSelfIssuedIdToken": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Decentralized Claims Protocol v1.0 self-issued ID token (JWT, EdDSA or ES256; iss = sub = the participant did:web, aud = the data space DID), with or without a `Bearer ` prefix — what external connectors such as Eclipse EDC send. The provider resolves the participant DID document, verifies the token, queries the participant Credential Service for a verifiable presentation and verifies it. The DID must belong to an active partner participant of that data space, and its host must be resolvable from this environment (staging: allow-listed hosts only; not available in production). Messages sent this way need no `proof`; a missing `Idempotency-Key` falls back to the consumerPid (initial requests) or the message `@id`. The usage-report endpoint still requires a signed message."
      },
      "dcpHolderIdToken": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "DCP v1.0 Issuer Service — the holder's self-issued ID token, `Bearer ` prefix required (JWT, EdDSA or ES256; iss = sub = the holder did:web, aud = the platform DID; signed with a key listed in the holder DID document `capabilityInvocation`; single-use `jti`; at most 10 minutes; 30 s clock skew). A `token` claim, when present, is echoed in the delivery token sent to the holder Credential Service."
      }
    },
    "schemas": {
      "IpItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "originType": {
            "type": "string",
            "enum": ["human", "ai", "hybrid"]
          },
          "price": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "creatorId": {
            "type": "string"
          },
          "creatorName": {
            "type": "string"
          },
          "thumbnailUrl": {
            "type": "string",
            "format": "uri"
          },
          "purchaseCount": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Error": {
        "type": "object",
        "description": "Error body. `error` is a short human-readable message, `code` the machine-readable reason. Some errors add fields (for example `issues` for VALIDATION_FAILED, `reason` for charge conflicts).",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                }
              }
            }
          },
          "reason": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "ConsentMode": {
        "type": "string",
        "enum": ["AUTO", "SCREENED", "DENY"],
        "description": "Creator consent for one action. AUTO = allowed, SCREENED = allowed only after approval (no approval record exists yet, so it is treated as blocked), DENY = refused. An unset value is DENY for aiTraining and commercialize."
      },
      "CatalogItem": {
        "type": "object",
        "properties": {
          "contentId": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "nullable": true,
            "description": "Content kind (ip_subtype), e.g. image, sticker."
          },
          "genreCode": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "synthId": {
            "type": "boolean",
            "description": "Whether an OGQ Synth ID is embedded. The value itself is delivered with the transfer manifest, not here."
          },
          "uci": {
            "type": "string",
            "enum": ["registered", "pending"]
          },
          "originType": {
            "type": "string",
            "enum": ["human", "ai", "hybrid", "unknown"]
          },
          "consent": {
            "type": "object",
            "properties": {
              "aiTraining": {
                "$ref": "#/components/schemas/ConsentMode"
              },
              "commercialize": {
                "$ref": "#/components/schemas/ConsentMode"
              },
              "derive": {
                "$ref": "#/components/schemas/ConsentMode"
              }
            }
          },
          "eligible": {
            "type": "boolean",
            "description": "Whether this item can be included in a bundle for the requested purpose. Only AUTO consent is eligible."
          },
          "ineligibleReason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "ai_training_denied",
              "commercialize_denied",
              "derive_denied",
              "requires_approval",
              null
            ]
          },
          "selfDescription": {
            "type": "string",
            "description": "Path to the DCAT-AP self-description of this content."
          }
        }
      },
      "CatalogSummaryRow": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "genre": {
            "type": "string",
            "nullable": true
          },
          "total": {
            "type": "integer"
          },
          "eligible": {
            "type": "integer",
            "description": "Items whose creator consented (AUTO) to the requested purpose."
          },
          "requiresApproval": {
            "type": "integer",
            "description": "SCREENED items. Not included in bundles until an approval record exists."
          },
          "denied": {
            "type": "integer",
            "description": "Items that refused, or never stated, consent for the requested purpose."
          }
        }
      },
      "BundleSpec": {
        "type": "object",
        "description": "The scope a bundle contract allows: a kind, optional genres and themes, and the single intent the content may be used for.",
        "required": ["kind", "purpose"],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Content kind (`ip_subtype`). Required — it is the leading index column."
          },
          "genres": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "themes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "purpose": {
            "type": "string",
            "enum": ["aiTraining", "commercialize", "derive", "use"]
          }
        }
      },
      "Offer": {
        "type": "object",
        "properties": {
          "offerId": {
            "type": "string"
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "licenseModel": {
            "type": "string",
            "enum": ["api", "non_exclusive", "exclusive"]
          },
          "pricing": {
            "type": "object",
            "nullable": true,
            "description": "`{model, unitPriceMicros, currency}`. Absent when the price has not been agreed yet; nothing is invoiced for an unpriced line.",
            "additionalProperties": true
          },
          "term": {
            "type": "object",
            "nullable": true,
            "description": "`{start, end}`. A flat-period contract with no end date is never billed — money is not charged on a term that does not exist.",
            "additionalProperties": true
          },
          "bundle": {
            "$ref": "#/components/schemas/BundleSpec"
          },
          "status": {
            "type": "string"
          }
        }
      },
      "JurisdictionHint": {
        "type": "object",
        "description": "What a destination jurisdiction requires. Send `legalAck` values in the order’s `acks[]`.",
        "properties": {
          "legalAck": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "duties": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reportCadenceDays": {
            "type": "integer"
          }
        }
      },
      "OrderRequest": {
        "type": "object",
        "required": ["offerId", "selection", "purpose"],
        "properties": {
          "offerId": {
            "type": "string"
          },
          "clientRef": {
            "type": "string",
            "nullable": true,
            "description": "Idempotency key fallback when the header is not sent."
          },
          "selection": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string"
              },
              "genres": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "themes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "contentIds": {
                "type": "array",
                "nullable": true,
                "maxItems": 200,
                "items": {
                  "type": "string"
                },
                "description": "Explicit selection. Items outside the offer scope come back as `outside_offer_scope`."
              }
            }
          },
          "destCountry": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2. It decides the jurisdiction, the minimum identity assurance and the required acknowledgements."
          },
          "acks": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Legal acknowledgements, e.g. `us_export_control` (US) or `gdpr_scc` (EU). Missing ones exclude every item as `legal_ack_missing`."
          },
          "purpose": {
            "type": "string",
            "enum": ["aiTraining", "commercialize", "derive", "use"],
            "description": "Must equal the offer’s `bundle.purpose`."
          }
        }
      },
      "OrderPage": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": ["expanding", "checked", "partially_blocked"],
            "description": "`expanding` while anything is left — a half-filled order never reports itself as complete."
          },
          "replayed": {
            "type": "boolean",
            "description": "True when the same Idempotency-Key returned the original order."
          },
          "accepted": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "contentId": {
                  "type": "string"
                },
                "transferId": {
                  "type": "string"
                }
              }
            }
          },
          "excluded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderExclusion"
            }
          },
          "remaining": {
            "type": "integer"
          },
          "nextCursor": {
            "type": "string",
            "nullable": true
          },
          "acceptedCount": {
            "type": "integer"
          },
          "blockedCount": {
            "type": "integer"
          }
        }
      },
      "OrderExclusion": {
        "type": "object",
        "properties": {
          "contentId": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "enum": [
              "ai_training_denied",
              "commercialize_denied",
              "derive_denied",
              "requires_approval",
              "outside_offer_scope",
              "content_not_available",
              "identity_loa_short",
              "intent_hash_invalid",
              "policy_denied",
              "contract_missing",
              "contract_not_found",
              "contract_unavailable",
              "contract_not_active",
              "contract_term_not_started",
              "contract_term_ended",
              "contract_odrl_missing",
              "contract_content_mismatch",
              "contract_inactive",
              "synth_id_missing",
              "legal_ack_missing",
              "gate_failed",
              "transfer_failed"
            ],
            "description": "Why the item is not in the bundle. `ai_training_denied` means the creator never consented to AI training (an unstated consent counts as refused). `requires_approval` is SCREENED consent, blocked until an approval record exists. `identity_loa_short` is about the partner’s named contact, not the content. `outside_offer_scope` is an explicitly named item that falls outside the offer's kind, genre or theme. `content_not_available` is an explicitly named id that could not be read at all — unknown id, not on sale, test data, or age-restricted; every id you send comes back in `accepted[]` or `excluded[]`, never neither. The `contract_*` reasons say which part of the contract failed, because the fix belongs to different people: `contract_missing` and `contract_not_found` mean the order's contract reference is wrong (yours to fix); `contract_not_active`, `contract_term_not_started` and `contract_term_ended` are the contract's own status and dates (ask OGQ to renew); `contract_odrl_missing` and `contract_content_mismatch` mean OGQ has to repair the contract — its status and dates will look perfectly fine to you, so do not go looking there; `contract_unavailable` means we could not read the contract at that moment, so retry. `contract_inactive` is only returned when the evidence does not say which of these it was."
          }
        }
      },
      "OrderSummary": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string"
          },
          "offerId": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "purpose": {
            "type": "string"
          },
          "destCountry": {
            "type": "string",
            "nullable": true
          },
          "destJurisdiction": {
            "type": "string"
          },
          "acks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "selection": {
            "type": "object",
            "additionalProperties": true
          },
          "accepted": {
            "type": "integer"
          },
          "excluded": {
            "type": "integer"
          },
          "excludedByReason": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "releasedCount": {
            "type": "integer"
          },
          "nextCursor": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "OrderReleaseResult": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string"
          },
          "released": {
            "type": "integer",
            "description": "Items that went out on this call."
          },
          "replayed": {
            "type": "integer",
            "description": "Items that had already gone out; the same envelope was returned, nothing was re-issued."
          },
          "failed": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "contentId": {
                  "type": "string"
                },
                "transferId": {
                  "type": "string"
                },
                "reason": {
                  "type": "string",
                  "description": "Why this item did not go out. The export gate is run again immediately before an item is released, so a gate reason can appear here even though the item passed at order time — the creator may have withdrawn consent, or the contract may have ended, in the days between ordering and fetching. Gate reasons use the same words as `OrderExclusion.reason` (`ai_training_denied`, `requires_approval`, the `contract_*` reasons, `synth_id_missing`, `legal_ack_missing`, `policy_denied`, `identity_loa_short`, `gate_failed`). Release errors are `transfer_not_found`, `transfer_not_checked`, `content_not_found`, `transfer_release_in_progress` (another call is releasing that same item right now — do not call `/release` for one order in parallel; wait and call again), or the credential error that stopped it. An item blocked by the gate here moves to `blocked` and is not retried on the next call."
                }
              }
            }
          },
          "remaining": {
            "type": "integer",
            "description": "Accepted items still waiting to go out. Call again while this is above zero."
          },
          "releasedCount": {
            "type": "integer",
            "description": "Total released for the order, recounted rather than incremented, so calling twice does not inflate it."
          },
          "batchSize": {
            "type": "integer"
          }
        }
      },
      "ManifestItem": {
        "type": "object",
        "properties": {
          "transferId": {
            "type": "string"
          },
          "contentId": {
            "type": "string"
          },
          "uci": {
            "type": "string",
            "nullable": true
          },
          "synthId": {
            "type": "string",
            "nullable": true
          },
          "hash": {
            "type": "string",
            "nullable": true,
            "description": "The same content hash the AI label credential carries, so the two can be compared."
          },
          "dataUrl": {
            "type": "string",
            "nullable": true,
            "description": "Signed URL, valid for one hour. Re-request the manifest page to get a fresh one."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "credential": {
            "type": "object",
            "properties": {
              "vc2Id": {
                "type": "string",
                "nullable": true
              },
              "sdJwtId": {
                "type": "string",
                "nullable": true
              },
              "sdJwt": {
                "type": "string",
                "nullable": true,
                "description": "Compact SD-JWT presentation of the transfer credential."
              }
            }
          },
          "aiLabelVcId": {
            "type": "string",
            "nullable": true
          },
          "licenseModel": {
            "type": "string"
          },
          "duties": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "duty": {
                  "type": "string"
                },
                "action": {
                  "type": "string"
                },
                "cadenceDays": {
                  "type": "integer"
                },
                "endpoint": {
                  "type": "string"
                }
              }
            }
          },
          "reportDueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "OrderManifestPage": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ManifestItem"
            }
          },
          "count": {
            "type": "integer"
          },
          "nextCursor": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "OrderUsageRequest": {
        "type": "object",
        "required": ["periodStart", "periodEnd", "usageType", "items"],
        "properties": {
          "periodStart": {
            "type": "string",
            "format": "date",
            "example": "2026-10-01"
          },
          "periodEnd": {
            "type": "string",
            "format": "date",
            "example": "2026-10-31"
          },
          "usageType": {
            "type": "string",
            "enum": ["training", "generation", "exposure", "api_call", "license_period"]
          },
          "usageUnit": {
            "type": "string",
            "nullable": true,
            "description": "Defaults per usage type (for example `tokens` for training)."
          },
          "action": {
            "type": "string",
            "enum": ["use", "derive", "commercialize", "aiTraining"],
            "default": "use"
          },
          "territory": {
            "type": "string",
            "nullable": true,
            "description": "ISO 3166-1 alpha-2. Outside the permitted territory the report is still recorded, with a violation."
          },
          "evidence": {
            "type": "string",
            "nullable": true,
            "description": "Optional SD-JWT presentation."
          },
          "items": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "type": "object",
              "properties": {
                "contentId": {
                  "type": "string"
                },
                "transferId": {
                  "type": "string"
                },
                "usageCount": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            }
          }
        }
      },
      "OrderUsageResult": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "string"
          },
          "recorded": {
            "type": "integer"
          },
          "deduplicated": {
            "type": "integer",
            "description": "Items whose report hash already existed — the same report, not a second one."
          },
          "violations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "transferId": {
                  "type": "string"
                },
                "kinds": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": ["territory_violation", "action_violation", "cadence_violation"]
                  }
                }
              }
            }
          },
          "notFound": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "contentId": {
                  "type": "string",
                  "nullable": true
                },
                "transferId": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "maxItems": {
            "type": "integer"
          }
        }
      },
      "DspMessage": {
        "type": "object",
        "description": "Eclipse Dataspace Protocol 2025-1 JSON-LD message, signed with a W3C Data Integrity proof (`eddsa-jcs-2022`) by the participant DID.",
        "required": ["@context", "@type", "proof"],
        "properties": {
          "@context": {},
          "@type": {
            "type": "string"
          },
          "consumerPid": {
            "type": "string"
          },
          "providerPid": {
            "type": "string"
          },
          "proof": {
            "type": "object"
          }
        },
        "additionalProperties": true
      },
      "SignedPartnerDocument": {
        "type": "object",
        "description": "A partner document signed with a W3C Data Integrity proof (`eddsa-jcs-2022`). The exact fields per endpoint are listed in the developer guide; the signature covers the whole document.",
        "required": ["proof"],
        "properties": {
          "proof": {
            "type": "object"
          }
        },
        "additionalProperties": true
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/catalog": {
      "get": {
        "summary": "Partner catalogue filtered by taxonomy and creator consent",
        "operationId": "listCatalog",
        "tags": ["Catalog"],
        "description": "Lists active, non-test, non-adult content for a partner, with the creator consent state of each item. This is the first of two places where consent is enforced; the transfer gate is the second.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "description": "Content kind (ip_subtype). Required because it is the leading column of the (ip_subtype, genre_code) index.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "genre",
            "in": "query",
            "required": false,
            "description": "Comma-separated genre codes (OR within the axis).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "theme",
            "in": "query",
            "required": false,
            "description": "Comma-separated theme codes (OR within the axis).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "purpose",
            "in": "query",
            "required": false,
            "description": "What the partner intends to do with the content. When given, items whose creator denied that action are not returned at all. When omitted nothing is filtered out, but eligible is still judged against aiTraining (see evaluatedPurpose).",
            "schema": {
              "type": "string",
              "enum": ["aiTraining", "commercialize", "derive", "use"]
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Keyset cursor from a previous nextCursor. Pages never repeat or skip a row.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CatalogItem"
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "nextCursor": {
                      "type": "string",
                      "nullable": true
                    },
                    "purpose": {
                      "type": "string",
                      "nullable": true,
                      "description": "The purpose the caller asked for, or null if none was given."
                    },
                    "evaluatedPurpose": {
                      "type": "string",
                      "description": "The purpose the eligible flag was judged against. When no purpose is given this is aiTraining — the strictest consent — so an item nobody consented to is never reported as eligible."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "kind_required or purpose_invalid"
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — key lookup failed; the request is not let through"
          }
        }
      }
    },
    "/catalog/summary": {
      "get": {
        "summary": "How many items can be bundled, per kind and genre",
        "operationId": "catalogSummary",
        "tags": ["Catalog"],
        "description": "Counts, grouped by kind and genre, of what a partner may take for the requested purpose. Use it to choose a category before ordering, instead of paging the whole catalogue.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "purpose",
            "in": "query",
            "required": false,
            "description": "What the partner intends to do with the content. When given, items whose creator denied that action are not returned at all, and only AUTO consent is marked eligible.",
            "schema": {
              "type": "string",
              "enum": ["aiTraining", "commercialize", "derive", "use"]
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "Optional comma-separated kinds to narrow the summary.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "purpose": {
                      "type": "string"
                    },
                    "byKind": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CatalogSummaryRow"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "purpose_invalid"
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/clearing/connectivity-fee": {
      "post": {
        "summary": "Record an exchange connectivity fee for a settled trade",
        "operationId": "postV1ClearingConnectivityFee",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "CONNECTIVITY_FEE_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tokenId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "venue": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "externalTradeRef": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "tradeValueUsdMicros": {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "feePercent": {
                    "type": "number",
                    "minimum": 0.001,
                    "maximum": 0.005
                  },
                  "buyerHolderId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "sellerHolderId": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 128
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "settledAt": {
                    "type": "string",
                    "maxLength": 40
                  }
                },
                "required": [
                  "tokenId",
                  "venue",
                  "externalTradeRef",
                  "tradeValueUsdMicros",
                  "feePercent",
                  "buyerHolderId",
                  "settledAt"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "txId": {},
                    "feeUsdMicros": {},
                    "feeUsd": {},
                    "venue": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "FEE_RECORD_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/clearing/license-fee": {
      "get": {
        "summary": "Read the global license status of a content item",
        "operationId": "getV1ClearingLicenseFee",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "contentId": {},
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "licenseId": {},
                    "tier": {},
                    "country_count": {},
                    "annual_fee": {},
                    "currency": {},
                    "coverage_start": {},
                    "coverage_end": {},
                    "renewal_status": {},
                    "days_remaining": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Register or renew a global license for a content item",
        "operationId": "postV1ClearingLicenseFee",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "LICENSE_FEE_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "countries": {
                    "minItems": 1,
                    "maxItems": 500,
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "period_months": {}
                },
                "required": ["contentId", "countries"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "CONTENT_NOT_OWNED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CONTENT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict. IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "LICENSE_RECORD_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/clearing/log": {
      "post": {
        "summary": "Submit a partner-signed clearing log and receive a signed receipt credential",
        "operationId": "postV1ClearingLog",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignedPartnerDocument"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same log (partner + payload hash) resent — the original receipt (`replayed: true`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "201": {
            "description": "Receipt issued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "CLEARING_LOG_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "PARTNER_SIGNER_MISMATCH.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/receipts/{id}": {
      "get": {
        "summary": "Read one of the caller's own clearing receipts",
        "operationId": "getV1ClearingReceipts",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "anchor": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/evidence/{id}": {
      "get": {
        "summary": "Offline-verifiable evidence bundle for one clearing receipt (parties only)",
        "description": "Returns the receipt VC, the Merkle inclusion proof of its ledger entry in an anchor batch (leaf payload, sibling hashes, batch root, chain hash and previous chain hash), the signing key and — when the log belongs to a DSP negotiation or transfer — the agreement attestation. Verify it without our server using `apps/web/scripts/dataspace/verify-evidence.mjs` or the public page `/dataspace/verify` (evidence bundle tab). Only fingerprints and ids are included, never the signed payload. Visible to the partner that sent the log and to the consumer or actors of the DSP process it records; anyone else gets 404.",
        "operationId": "getV1ClearingEvidence",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Clearing log id (`dcl_…`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The evidence bundle.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": ["OgqClearingEvidenceBundle"]
                    },
                    "version": {
                      "type": "integer"
                    },
                    "generatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "subject": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": ["receipt", "agreement"]
                        },
                        "id": {
                          "type": "string"
                        }
                      }
                    },
                    "issuerKeys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "verificationMethod": {
                            "type": "string"
                          },
                          "publicKeyMultibase": {
                            "type": "string"
                          },
                          "didDocument": {
                            "type": ["string", "null"]
                          }
                        }
                      }
                    },
                    "attestation": {
                      "type": ["object", "null"],
                      "description": "OgqAgreementAttestationCredential (VC 2.0, eddsa-jcs-2022) — null until the agreement is FINALIZED."
                    },
                    "receipts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "logId": {
                            "type": "string"
                          },
                          "receipt": {
                            "type": ["object", "null"]
                          },
                          "inclusion": {
                            "type": ["object", "null"],
                            "description": "Merkle inclusion proof of the receipt's ledger entry in an anchor batch: leafPayload, leafIndex, proof (sibling hashes), batch {seq, merkleRoot, chainHash, prevChainHash, anchorStatus}."
                          },
                          "inclusionReason": {
                            "type": ["string", "null"]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND — no such log, or the caller is not a party.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/agreements/{id}/attestation": {
      "get": {
        "summary": "Clearing attestation and evidence bundle of a contract agreement (parties only)",
        "description": "Returns the clearing house attestation of a FINALIZED DSP contract agreement — the consumer's signed agreement verification and the provider's signed agreement, fingerprinted and countersigned by the data space clearing key (IDSA RAM 4 §3.4.3 triple-signed agreement) — together with the receipt and Merkle inclusion proof of every signed negotiation step. `attestation` is null until the agreement is finalized. Verifiable offline with `verify-evidence.mjs`. Only the agreement's consumer or a provider participant recorded on the agreement ledger can read it; anyone else gets 404.",
        "operationId": "getV1ClearingAgreementAttestation",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Contract agreement id (`urn:uuid:…`, URL-encoded).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The attestation and evidence bundle.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": ["OgqClearingEvidenceBundle"]
                    },
                    "version": {
                      "type": "integer"
                    },
                    "generatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "subject": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": ["receipt", "agreement"]
                        },
                        "id": {
                          "type": "string"
                        }
                      }
                    },
                    "issuerKeys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "verificationMethod": {
                            "type": "string"
                          },
                          "publicKeyMultibase": {
                            "type": "string"
                          },
                          "didDocument": {
                            "type": ["string", "null"]
                          }
                        }
                      }
                    },
                    "attestation": {
                      "type": ["object", "null"],
                      "description": "OgqAgreementAttestationCredential (VC 2.0, eddsa-jcs-2022) — null until the agreement is FINALIZED."
                    },
                    "receipts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "logId": {
                            "type": "string"
                          },
                          "receipt": {
                            "type": ["object", "null"]
                          },
                          "inclusion": {
                            "type": ["object", "null"],
                            "description": "Merkle inclusion proof of the receipt's ledger entry in an anchor batch: leafPayload, leafIndex, proof (sibling hashes), batch {seq, merkleRoot, chainHash, prevChainHash, anchorStatus}."
                          },
                          "inclusionReason": {
                            "type": ["string", "null"]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND — no such agreement, or the caller is not a party.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/revalidation-requests": {
      "post": {
        "summary": "Ask a trusted external verifier to re-verify a clearing receipt or agreement (parties only)",
        "description": "Creates an external re-verification request (NIA reference model v2 B07). Name one verifier from the trusted list configured on this environment (`CLEARING_REVERIFIERS` — DID plus pinned Ed25519 key; empty by default, and production does not read it, so the endpoint answers 404 until a verifier is configured). The response carries a one-time scope token: hand it to that verifier out of band. With `Authorization: Bearer <scopeToken>` the verifier pulls the evidence bundle from `GET /api/v1/clearing/revalidation-requests/{id}/evidence` (same bundle as `/clearing/evidence/{id}` or `/clearing/agreements/{id}/attestation`, assembled for the requesting party) and posts its signed result credential (VC 2.0 `eddsa-jcs-2022`, type `OgqClearingRevalidationResult`, credentialSubject `revalidationRequest` · `subject` · `evidenceDigest` (the digest it pulled) · `outcome` `confirmed`|`discrepancy` · optional `findings`) to `POST /api/v1/clearing/revalidation-requests/{id}/result`. The scope token covers that one request for 7 days; only its SHA-256 is stored. OGQ sends nothing to the verifier. Every step is an append-only ledger row.",
        "operationId": "postV1ClearingRevalidationRequests",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["subject", "verifierDid"],
                "properties": {
                  "subject": {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": ["agreement", "receipt"]
                      },
                      "id": {
                        "type": "string"
                      }
                    }
                  },
                  "verifierDid": {
                    "type": "string",
                    "description": "DID of a verifier on the trusted list (`did:web:` or `did:key:`)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Request created. `scopeToken` is shown only here.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestId": {
                      "type": "string",
                      "description": "`rv-<uuid>`"
                    },
                    "subject": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": ["agreement", "receipt"]
                        },
                        "id": {
                          "type": "string"
                        }
                      }
                    },
                    "verifierDid": {
                      "type": "string"
                    },
                    "scopeToken": {
                      "type": "string",
                      "description": "`ogqrv_…` — give it to the verifier; valid for this request only, 7 days."
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "evidencePath": {
                      "type": "string"
                    },
                    "resultPath": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "INVALID_SUBJECT · INVALID_VERIFIER — malformed subject or verifier DID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "VERIFIER_NOT_TRUSTED — the named verifier is not on the trusted list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND — re-verification is not offered here (empty trusted list), or the caller is not a party of the subject.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/revalidation-requests/{id}": {
      "get": {
        "summary": "Status of an external re-verification request (requesting partner only)",
        "description": "Returns the evidence digests the verifier pulled and, once recorded, its result (outcome, digest it re-verified, the signed result credential and its SHA-256). The scope token is never returned again. Another partner's request, an unknown id or an empty trusted list all answer 404.",
        "operationId": "getV1ClearingRevalidationRequest",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Request id (`rv-<uuid>`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestId": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": ["agreement", "receipt"]
                        },
                        "id": {
                          "type": "string"
                        }
                      }
                    },
                    "verifierDid": {
                      "type": "string"
                    },
                    "expiresAt": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "pulls": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "evidenceDigest": {
                            "type": "string"
                          },
                          "at": {
                            "type": ["string", "null"]
                          }
                        }
                      }
                    },
                    "result": {
                      "type": ["object", "null"],
                      "properties": {
                        "outcome": {
                          "type": "string",
                          "enum": ["confirmed", "discrepancy"]
                        },
                        "evidenceDigest": {
                          "type": "string"
                        },
                        "resultVcSha256": {
                          "type": "string"
                        },
                        "verifiableCredential": {
                          "type": ["object", "null"]
                        },
                        "at": {
                          "type": ["string", "null"]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND — no such request for this partner, or re-verification is not offered here.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/revalidation-requests/{id}/evidence": {
      "get": {
        "summary": "Pull the evidence bundle of a re-verification request (designated verifier only)",
        "description": "Called by the trusted external verifier named in the request, with the scope token that was handed to the requesting partner (valid for that request only, 7 days). The bundle is assembled with the requesting partner's view — the verifier never sees more than the party did. Each distinct bundle digest pulled is recorded once (append-only). An empty trusted list answers 404.",
        "operationId": "getV1ClearingRevalidationEvidence",
        "tags": ["Clearing"],
        "security": [
          {
            "revalidationScopeToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Request id (`rv-<uuid>`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The evidence bundle and its digest. Bind the result credential to this digest.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestId": {
                      "type": "string"
                    },
                    "evidenceDigest": {
                      "type": "string",
                      "description": "`sha256:<hex>` of the canonical bundle."
                    },
                    "bundle": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "SCOPE_TOKEN_INVALID · SCOPE_TOKEN_EXPIRED — the scope token is missing, wrong or past its expiry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "VERIFIER_NOT_TRUSTED — the designated verifier is no longer on the trusted list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND — unknown request, no evidence for its subject, or re-verification is not offered here.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/revalidation-requests/{id}/result": {
      "post": {
        "summary": "Record the signed re-verification result (designated verifier only)",
        "description": "Body `{ verifiableCredential }` — a VC 2.0 secured with `eddsa-jcs-2022`, type `OgqClearingRevalidationResult`, signed by the designated verifier's key pinned on the trusted list (the issuer DID document is not fetched). The credential must bind the request id, the subject and an evidence digest the verifier pulled, and state `confirmed` or `discrepancy`. One result per request; a second one answers 409. Recorded append-only.",
        "operationId": "postV1ClearingRevalidationResult",
        "tags": ["Clearing"],
        "security": [
          {
            "revalidationScopeToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Request id (`rv-<uuid>`).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["verifiableCredential"],
                "properties": {
                  "verifiableCredential": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Result recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requestId": {
                      "type": "string"
                    },
                    "outcome": {
                      "type": "string",
                      "enum": ["confirmed", "discrepancy"]
                    },
                    "resultVcSha256": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "RESULT_VC_MALFORMED · RESULT_VC_TOO_LARGE · RESULT_SIGNATURE_INVALID · RESULT_VC_NOT_VALID_NOW · RESULT_BINDING_MISMATCH · RESULT_EVIDENCE_NOT_PULLED · RESULT_OUTCOME_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "SCOPE_TOKEN_INVALID · SCOPE_TOKEN_EXPIRED — the scope token is missing, wrong or past its expiry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "VERIFIER_NOT_TRUSTED · RESULT_ISSUER_NOT_DESIGNATED — not the designated, still-trusted verifier.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND — unknown request, or re-verification is not offered here.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "RESULT_ALREADY_RECORDED — this request already has a result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "RESULT_VC_TOO_LARGE — the body exceeds the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/peer-query": {
      "post": {
        "summary": "Answer a query from a peer clearing house (hash-level log summary)",
        "description": "IDSA Clearing House W10 (clearing houses communicate) — the receiving side, shaped after the IDS Clearing House query. A peer clearing house that represents a party of the agreement (assigner or assignee DID) asks what this clearing house recorded for one agreement or one transfer. The answer carries ids, times, fingerprints, receipt ids, the agreement attestation id and archive bundle ids only — no message bodies; bodies sealed for the two parties are reported as an envelope fingerprint. 50 items per page, oldest first. Each answered query is recorded append-only (`clearing_peer_query_received`). Unknown peer, empty allow list, or an agreement the peer does not represent all answer the same 404.",
        "operationId": "postV1ClearingPeerQuery",
        "tags": ["Clearing"],
        "security": [{ "clearingPeerIdToken": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "description": "Exactly one of `agreementId` or `transferPid`.",
                "properties": {
                  "agreementId": { "type": "string" },
                  "transferPid": { "type": "string" },
                  "since": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Only logs received at or after this time (offset required)."
                  },
                  "page": { "type": "integer", "minimum": 1, "maximum": 10000, "default": 1 }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One page of the agreement's clearing log summary.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agreementId": { "type": "string" },
                    "transferPid": { "type": "string" },
                    "since": { "type": ["string", "null"] },
                    "page": { "type": "integer" },
                    "size": { "type": "integer" },
                    "total": { "type": "integer" },
                    "totalPages": { "type": "integer" },
                    "truncated": { "type": "boolean" },
                    "attestationId": { "type": ["string", "null"] },
                    "archiveBundles": { "type": "array", "items": { "type": "string" } },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "logId": { "type": "string" },
                          "eventType": { "type": "string" },
                          "relatedKind": { "type": "string" },
                          "occurredAt": { "type": "string", "format": "date-time" },
                          "receivedAt": { "type": "string", "format": "date-time" },
                          "payloadHash": {
                            "type": "string",
                            "description": "SHA-256 of the logged message (JCS)."
                          },
                          "receiptVcId": { "type": "string" },
                          "archiveId": {
                            "type": "string",
                            "description": "Daily signed archive bundle that holds this log, when sealed."
                          },
                          "sealedEnvelopeSha256": {
                            "type": "string",
                            "description": "When the body was sealed for the two parties (contract logging level `encrypted`), only the fingerprint of the envelope — never the envelope or the plaintext."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "INVALID_QUERY — body shape (exactly one of agreementId | transferPid, since with offset, page 1..10000, no other fields).",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "401": {
            "description": "PEER_TOKEN_MISSING · DCP_TOKEN_INVALID · DCP_TOKEN_EXPIRED · DCP_SIGNATURE_INVALID · DCP_TOKEN_REPLAYED — token missing, wrong audience, bad signature, expired or reused.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "404": {
            "description": "NOT_FOUND — peer queries are not offered here, the peer is not on the allow list, or no such agreement/transfer that the peer represents.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "413": {
            "description": "QUERY_TOO_LARGE — body over 4 KB.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "503": {
            "description": "DCP_REPLAY_CHECK_UNAVAILABLE · PEER_QUERY_RECORD_UNAVAILABLE — the query could not be recorded; try again.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/clearing/logs": {
      "get": {
        "summary": "Query your clearing logs page by page — per agreement for its parties (IDSA Clearing House query)",
        "description": "Returns clearing log entries ordered by the time we received them. Without `agreement` it lists the logs this partner sent itself. With `agreement` it lists the logs of that agreement — the agreement id, its negotiation and the transfers opened under it — written by a party of that process or bound to a DSP state transition; logs that someone else filed against the same process id are excluded. Only the agreement's consumer and the provider organization's active operator/provider participants may query an agreement; anyone else gets the same 404 as for an unknown agreement. Items carry ids, fingerprints, times and kinds only — never the signed payload, requester keys or partner ids. An agreement query also returns the invoice lines that point at the agreement's transfers. Fetch the offline-verifiable bundle of any item from `evidence`.",
        "operationId": "getV1ClearingLogs",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "agreement",
            "in": "query",
            "required": false,
            "description": "Agreement id. Omit to list the logs you sent yourself.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Received at or after — `YYYY-MM-DD` (start of day, UTC) or an ISO 8601 date-time with an offset.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Received at or before — `YYYY-MM-DD` (end of day, UTC) or an ISO 8601 date-time with an offset.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000,
              "default": 1
            }
          },
          {
            "name": "size",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Order by received time.",
            "schema": {
              "type": "string",
              "enum": ["desc", "asc"],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agreement": {
                      "type": ["object", "null"],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "negotiationId": {
                          "type": "string"
                        },
                        "transferCount": {
                          "type": "integer"
                        },
                        "viewerRole": {
                          "type": "string",
                          "enum": ["consumer", "provider"]
                        },
                        "truncated": {
                          "type": "boolean"
                        }
                      }
                    },
                    "from": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "to": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "sort": {
                      "type": "string",
                      "enum": ["desc", "asc"]
                    },
                    "page": {
                      "type": "integer"
                    },
                    "size": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "logId": {
                            "type": "string"
                          },
                          "eventType": {
                            "type": "string"
                          },
                          "relatedKind": {
                            "type": "string"
                          },
                          "relatedId": {
                            "type": "string"
                          },
                          "occurredAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "receivedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "payloadHash": {
                            "type": "string",
                            "description": "SHA-256 of the signed message (hex)."
                          },
                          "receiptVcId": {
                            "type": "string"
                          },
                          "recordedBy": {
                            "type": "string",
                            "enum": ["you", "counterparty", "operator"]
                          },
                          "evidence": {
                            "type": "string",
                            "description": "Path of the evidence bundle for this log."
                          },
                          "sealedPayload": {
                            "type": "object",
                            "description": "Present only when the agreement's clearing log level is encrypted (ogq:loggingLevel). The log payload as a JWE (General JSON, alg ECDH-ES+A256KW, enc A256GCM, X25519) sealed to the two contract parties; the operator cannot open it."
                          }
                        }
                      }
                    },
                    "invoiceLines": {
                      "type": ["array", "null"],
                      "description": "Present on agreement queries. Invoice lines that point at the agreement's transfers (null when invoices cannot be read).",
                      "items": {
                        "type": "object",
                        "properties": {
                          "invoiceId": {
                            "type": "string"
                          },
                          "period": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "source": {
                            "type": "string"
                          },
                          "transferId": {
                            "type": "string"
                          },
                          "usageType": {
                            "type": "string"
                          },
                          "usageUnit": {
                            "type": "string"
                          },
                          "usageCount": {
                            "type": "integer"
                          },
                          "amountMicros": {
                            "type": "integer"
                          },
                          "unpriced": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query (`INVALID_QUERY`)."
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "404": {
            "description": "Unknown agreement, or you are not a party to it."
          }
        }
      }
    },
    "/clearing/signers": {
      "get": {
        "summary": "Read the caller's registered clearing signer and its history",
        "operationId": "getV1ClearingSigners",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Register, rotate or revoke the clearing signer (DID + key)",
        "operationId": "postV1ClearingSigners",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignedPartnerDocument"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same registration resent (`replayed: true`) or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "201": {
            "description": "Registered or rotated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "SIGNER_REGISTRATION_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "DID hosted on an OGQ host.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Already exists / not found / DID used by another partner / concurrent registration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "The did:web document could not be fetched.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/stablecoin-settle": {
      "post": {
        "summary": "Stablecoin payout request — closed (always 503 PAYOUT_NOT_ENABLED until the payout queue exists)",
        "operationId": "postV1ClearingStablecoinSettle",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/wise-transfer": {
      "get": {
        "summary": "Wise payout status — closed (503 PAYOUT_NOT_ENABLED while the payout gate is off)",
        "operationId": "getV1ClearingWiseTransfer",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "transferId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transferId": {},
                    "status": {},
                    "sourceAmount": {},
                    "targetAmount": {},
                    "rate": {},
                    "estimatedDelivery": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Wise payout — closed (503 PAYOUT_NOT_ENABLED while the payout gate is off)",
        "operationId": "postV1ClearingWiseTransfer",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "WISE_TRANSFER_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "creatorId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "amountKrw": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "targetCurrency": {
                    "type": "string",
                    "pattern": "^[A-Za-z]{3}$"
                  },
                  "recipientName": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "bankAccount": {
                    "type": "string",
                    "maxLength": 64
                  },
                  "country": {
                    "type": "string",
                    "maxLength": 64
                  }
                },
                "required": [
                  "creatorId",
                  "amountKrw",
                  "targetCurrency",
                  "recipientName",
                  "bankAccount",
                  "country"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transferId": {},
                    "amountSource": {},
                    "amountTarget": {},
                    "exchangeRate": {},
                    "fee": {},
                    "estimatedDelivery": {},
                    "status": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED · IDEMPOTENCY_REQUEST_IN_PROGRESS · RESULT_UNKNOWN (an earlier call with this key ended with an unknown result; it is never retried).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "RESULT_UNKNOWN — the transfer call may have reached the provider.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "TRANSFER_NOT_STARTED — failed before the transfer call; nothing was sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "When the gate opens: the same `Idempotency-Key` never sends money twice. A failure before the transfer call is `502 TRANSFER_NOT_STARTED` (the key is released). A failure during or after the transfer call is `500 RESULT_UNKNOWN` and the key is locked — the same key then returns `409 RESULT_UNKNOWN`; check the transfer status before trying again.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/copyright/register": {
      "post": {
        "summary": "Record copyright registrations for a content item per jurisdiction (KR · US · EU · WIPO)",
        "operationId": "postV1CopyrightRegister",
        "tags": ["Copyright"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "COPYRIGHT_REGISTER_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "jurisdictions": {
                    "maxItems": 16,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 16
                    }
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "creatorName": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "contentHash": {
                    "type": "string",
                    "maxLength": 128
                  }
                },
                "required": ["contentId"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "contentId": {},
                    "registrations": {},
                    "total": {
                      "type": "integer"
                    },
                    "registered_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request. IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "COPYRIGHT_REGISTER_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/dataspace/contracts": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "List smart contracts visible to the caller (a partner sees only its own)",
        "operationId": "getDataspaceContracts",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "ogqAdminSession": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "PARTNER_IDENTITY_MISSING — the key has no partner identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/gx/agreements/{id}/dua.json": {
      "servers": [{ "url": "https://stg.nova.ogq.me/api", "description": "Staging (current)" }],
      "get": {
        "summary": "Gaia-X Data Usage Agreement credential of a finalized contract agreement (parties only)",
        "description": "Returns the `gx:DataUsageAgreement` VC-JWT issued when a DSP contract negotiation reached FINALIZED (Gaia-X Compliance Document 4.0.0, D1.1.6a). Only the agreement's consumer, a provider participant recorded on the agreement ledger, or a top-level administrator can read it; anyone else gets 404. Default body is the compact VC-JWT (`application/vc+jwt`); `view=json` adds the decoded credential. Signed with the data space clearing key (EdDSA) — verify against the issuer DID document. When the consumer accepted the agreement through a DID-signed verification message, that signed message is embedded in the credential `evidence` (verify it against the consumer DID document). Nothing is submitted to a Gaia-X clearing house.",
        "operationId": "getGaiaxDataUsageAgreement",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "ogqAdminSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Contract agreement id (`urn:uuid:…`, URL-encoded).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "description": "`json` to receive the decoded credential alongside the VC-JWT.",
            "schema": {
              "type": "string",
              "enum": ["json"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The credential.",
            "content": {
              "application/vc+jwt": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "vcId": {
                      "type": "string"
                    },
                    "agreementId": {
                      "type": "string"
                    },
                    "issuer": {
                      "type": "string"
                    },
                    "jwt": {
                      "type": "string"
                    },
                    "credential": {
                      "type": ["object", "null"]
                    },
                    "consumerAcceptance": {
                      "type": "object",
                      "description": "How the consumer accepted the agreement (credential `evidence`): `did-data-integrity` = the consumer signed the agreement digest with its DID key (signed message embedded) · `dsp-verification-digest` = digest of the consumer's ContractAgreementVerificationMessage only · `provider_only` = no consumer evidence (older agreements). `notary` = trusted-source notarisation slot (`none` or `not_connected`; nothing is sent).",
                      "properties": {
                        "method": {
                          "type": "string",
                          "enum": ["did-data-integrity", "dsp-verification-digest", "provider_only"]
                        },
                        "notary": {
                          "type": ["string", "null"]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "INVALID_API_KEY · API_KEY_EXPIRED — the partner key is unknown or expired · UNAUTHENTICATED — no key and no administrator session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signed in, but not an administrator (no partner key sent).",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "404": {
            "description": "DUA_NOT_FOUND — no such credential, or the caller is not a party to the agreement.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/dsp/processes/{pid}": {
      "get": {
        "summary": "Negotiation or transfer detail — event flow, provider messages, data usage agreement (parties only)",
        "operationId": "getV1DataspaceDspProcesses",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/dsp/provider-actions": {
      "post": {
        "summary": "Provider decision on a negotiation or transfer (signed `OgqDspProviderAction`)",
        "description": "Negotiation actions: `offer`, `agree`, `finalize`, `terminate`, `revoke`. Transfer actions: `start`, `complete`, `suspend`, `terminate`. Per DSP 2025-1 a FINALIZED negotiation is final — `terminate` is refused (409 `INVALID_TRANSITION`). To end a finalized agreement, send `revoke`: the negotiation state stays as it is and the usage agreement is recorded as revoked, after which transfers, transfer tokens, data pulls and compute-to-data jobs under that agreement are refused and completed compute-to-data results are withheld. A rights holder withdrawing consent for the asset revokes the agreement the same way.",
        "operationId": "postV1DataspaceDspProviderActions",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignedPartnerDocument"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Applied; emitted protocol messages are returned in `emitted`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed action or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "SELF_DEALING or signer/participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/dataspace/dsp/transfers/{pid}/edr": {
      "get": {
        "summary": "Data address of a started transfer (`TransferStartMessage`, 5-minute token, `no-store`)",
        "operationId": "getV1DataspaceDspTransfersEdr",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Agreement or consent no longer valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Transfer is not started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/c2d/jobs": {
      "get": {
        "summary": "List the caller's contract-based compute-to-data jobs at an organization, or read one",
        "description": "Compute-to-data on a provider organization's asset, on the basis of a DSP agreement in force (FINALIZED, not revoked or terminated, time constraints valid) in which the calling partner is the consumer. The computation runs on the provider side and the provider's staff approve and run it; the caller only receives the job state and aggregate numeric metrics (`resultOnly`) — never the original data. Without `jobId` the response lists the caller's own jobs (latest 100) and the asset ids it may request now; with `jobId` it returns that one job. Jobs of other consumers, staff jobs and jobs of other organizations answer 404.",
        "operationId": "getV1DataspaceC2dJobs",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "tenant",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Provider organization slug."
          }
        ],
        "responses": {
          "200": {
            "description": "The caller's jobs and requestable assets, or one job. A completed job carries `result` (numeric metrics only) while the agreement is still in force and the rights holder's consent for the asset still stands; otherwise `result` is null and `resultWithheld` names the reason (`C2D_CONTRACT_REQUIRED` — the agreement ended, including when the rights holder withdrew consent; `ASSET_CONSENT_REQUIRED` — consent withdrawn).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jobs": {},
                    "eligibleAssets": {},
                    "job": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "C2D_CONSUMER_NOT_ELIGIBLE — the caller is not an active participant of this organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "TENANT_NOT_FOUND (unknown organization, or the key is bound to another one) · C2D_JOB_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later). Also TENANT_C2D_TABLE_NOT_PROVISIONED where the job table is not provisioned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Request a contract-based compute-to-data job on a provider organization's asset",
        "description": "Requires a DSP agreement in force for that asset in which the calling partner is the consumer. Only the cost-free `statistics` algorithm (database aggregate) is enabled; no external AI call and no charge. The aggregate population is limited to the assets covered by the caller's own agreements. Sending the same request while a job for the same asset and algorithm is still open returns that job (`created: false`).",
        "operationId": "postV1DataspaceC2dJobs",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenant", "assetId"],
                "properties": {
                  "tenant": {
                    "type": "string",
                    "description": "Provider organization slug."
                  },
                  "assetId": {
                    "type": "string",
                    "description": "Content id of the asset under agreement."
                  },
                  "algorithm": {
                    "type": "string",
                    "enum": ["statistics"],
                    "default": "statistics"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "An open job for the same asset and algorithm already existed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {},
                    "created": {}
                  }
                }
              }
            }
          },
          "201": {
            "description": "Job requested. The provider organization's staff approve and run it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "BODY_INVALID · ASSET_ID_INVALID · ALGORITHM_INVALID · C2D_ALGORITHM_NOT_ENABLED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "C2D_CONSUMER_NOT_ELIGIBLE · C2D_CONTRACT_REQUIRED (no agreement in force for that asset) · ASSET_CONSENT_REQUIRED · C2D_POLICY_DENIED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "TENANT_NOT_FOUND (unknown organization, or the key is bound to another one).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "C2D_TOO_MANY_OPEN_JOBS — 20 open jobs per consumer per organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later). Also POLICY_CHECK_UNAVAILABLE · TENANT_C2D_TABLE_NOT_PROVISIONED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/labels": {
      "get": {
        "summary": "List the caller's own compliance labels",
        "operationId": "getV1DataspaceLabels",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "tenant",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "dataspace": {},
                    "count": {
                      "type": "integer"
                    },
                    "labels": {},
                    "gxExternalAuditLevels": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "TENANT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/labels/{labelId}/heartbeat": {
      "post": {
        "summary": "Send a cloud-provider log heartbeat for a compliance label",
        "description": "Records the heartbeat. A heartbeat moves an `at_risk` label back to `active` only while its credential is still valid. A `suspended` label stays `suspended` (its credential was revoked) — it returns to `active` only through an operator re-review that issues a new credential.",
        "operationId": "postV1DataspaceLabelsHeartbeat",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "labelId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["logHash"],
                "properties": {
                  "logHash": {
                    "type": "string",
                    "pattern": "^[0-9a-fA-F]{64}$"
                  },
                  "logCount": {
                    "type": "integer"
                  },
                  "csp": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "region": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "metrics": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Duplicate heartbeat (`duplicate: true`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {},
                    "labelId": {},
                    "duplicate": {},
                    "status": {},
                    "transition": {},
                    "lastHeartbeatAt": {}
                  }
                }
              }
            }
          },
          "201": {
            "description": "Recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_LABEL_ID · BODY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "LABEL_CLOSED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/membership": {
      "get": {
        "summary": "List the caller's dataspace memberships",
        "operationId": "getV1DataspaceMembership",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "tenant",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "purposes": {},
                    "proof": {
                      "type": "object"
                    },
                    "keyTenantBound": {},
                    "memberships": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "TENANT_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Apply to join an organization dataspace (signed join request)",
        "operationId": "postV1DataspaceMembership",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignedPartnerDocument"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same request resent (`replayed: true`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "201": {
            "description": "Requested.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "JOIN_REQUEST_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key bound to another organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Organization not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict with the current membership state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/provenance/submissions": {
      "post": {
        "summary": "Submit a signed W3C PROV-O history about one of our contents",
        "description": "Adds the partner's own provenance (activities that used or derived from one of our contents) to our provenance graph as a signed `prov:Bundle` (NIA reference model v2 E03). `document` is PROV-O JSON-LD: `@context` declaring `http://www.w3.org/ns/prov#`, `@graph` of 1–500 nodes typed `prov:Entity`, `prov:Activity` or `prov:Agent`, property names prefixed `prov:`, `dct:`, `rdfs:` or `ogq:`, referencing `ogq:content/{contentId}` at least once and not minting any other `ogq:` node IRI (`ogq:` class names such as `ogq:DataAccess` are fine). It must carry a VC 2.0 Data Integrity proof (`eddsa-jcs-2022`) made with the signer registered for this partner key (`POST /clearing/signers`). The stored document is returned verbatim by `GET /dataspace/provenance/submissions/{id}`, and appears as a bundle in the administrator view of the content's PROV-O export. Re-sending the same document returns the first record (200).",
        "operationId": "postV1DataspaceProvenanceSubmissions",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["contentId", "document"],
                "properties": {
                  "contentId": {
                    "type": "string"
                  },
                  "document": {
                    "type": "object",
                    "description": "Signed PROV-O JSON-LD document (`@context`, `@graph`, `proof`)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same document already received — the first record.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "importId": {
                      "type": "string"
                    },
                    "contentId": {
                      "type": "string"
                    },
                    "signerDid": {
                      "type": "string"
                    },
                    "triples": {
                      "type": "integer",
                      "description": "Number of (node, property, value) statements in `@graph` (`@type` counts once per type, arrays once per element)."
                    },
                    "docSha256": {
                      "type": "string"
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Received.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "importId": {
                      "type": "string"
                    },
                    "contentId": {
                      "type": "string"
                    },
                    "signerDid": {
                      "type": "string"
                    },
                    "triples": {
                      "type": "integer",
                      "description": "Number of (node, property, value) statements in `@graph` (`@type` counts once per type, arrays once per element)."
                    },
                    "docSha256": {
                      "type": "string"
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "INVALID_CONTENT_ID · PROV_* (malformed document, node type or property not allowed, foreign `ogq:` IRI, content not referenced, graph size, proof missing) · PROV_SIGNATURE_INVALID (does not verify with the registered key).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "PARTNER_SIGNER_NOT_REGISTERED · PARTNER_SIGNER_MISMATCH — no registered signer, or signed by another DID / verification method.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "CONTENT_NOT_FOUND — no provenance for that content.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PROV_DOCUMENT_TOO_LARGE — over 256 KB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE · PARTNER_SIGNER_REGISTRY_UNAVAILABLE — the key store or signer registry could not be read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/provenance/submissions/{id}": {
      "get": {
        "summary": "Read back a PROV-O history this partner submitted (verbatim)",
        "description": "Returns the summary and the signed document exactly as received. Another partner's import or an unknown id answers 404.",
        "operationId": "getV1DataspaceProvenanceSubmission",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Import id (UUID).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The import.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "importId": {
                      "type": "string"
                    },
                    "contentId": {
                      "type": "string"
                    },
                    "signerDid": {
                      "type": "string"
                    },
                    "triples": {
                      "type": "integer",
                      "description": "Number of (node, property, value) statements in `@graph` (`@type` counts once per type, arrays once per element)."
                    },
                    "docSha256": {
                      "type": "string"
                    },
                    "document": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "NOT_FOUND — no such import for this partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/tenant-assets": {
      "get": {
        "summary": "List assets self-mapped by the calling organization operator",
        "operationId": "getV1DataspaceTenantAssets",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "tenant",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tenant": {},
                    "roles": {},
                    "items": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Self-map an asset into an organization dataspace (creator consent is requested)",
        "operationId": "postV1DataspaceTenantAssets",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["tenant", "kind", "id"],
                "properties": {
                  "tenant": {
                    "type": "string",
                    "description": "Organization slug."
                  },
                  "kind": {
                    "type": "string"
                  },
                  "id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mapping already existed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "created": {},
                    "status": {},
                    "notified": {},
                    "roles": {}
                  }
                }
              }
            }
          },
          "201": {
            "description": "Mapping created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "BODY_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an operator of this organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Organization or asset not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflict with the current mapping state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/transfers/{id}/usage": {
      "post": {
        "summary": "Report post-transfer usage for a released cross-border transfer",
        "operationId": "postV1DataspaceTransfersUsage",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transferId": {},
                    "recorded": {},
                    "deduplicated": {},
                    "usageId": {},
                    "reportHash": {},
                    "violations": {},
                    "alerts": {},
                    "cadenceDays": {},
                    "evidence": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_json",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "transfer_not_released",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/vc/import": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Import an externally issued verifiable credential",
        "operationId": "postDataspaceVcImport",
        "tags": ["Dataspace"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "ogqAdminSession": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["vc"],
                "properties": {
                  "vc": {
                    "type": "object",
                    "description": "W3C Verifiable Credential (JSON-LD) issued by a trusted issuer."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "vcId": {},
                    "issuer": {},
                    "type": {},
                    "imported": {
                      "type": "boolean"
                    },
                    "keySource": {},
                    "demo": {
                      "type": "boolean",
                      "description": "True when the issuer is a DEMO trust anchor (did:ogq:demo-*), not a real external issuer."
                    },
                    "label": {
                      "type": ["string", "null"],
                      "description": "'DEMO' for demo-anchor issuers, otherwise null."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "bad_request · issuer_missing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "already_imported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_proof",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream service failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/negotiations/request": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — start a negotiation (`ContractRequestMessage`)",
        "operationId": "postDsp20251NegotiationsRequest",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same `Idempotency-Key` resent — the same negotiation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "201": {
            "description": "`ContractNegotiation` created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "ASSET_CONSENT_REQUIRED or signer/participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Offer or dataset not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/dsp/2025-1/negotiations/{pid}": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Dataspace Protocol 2025-1 — contract negotiation state (`ContractNegotiation`, parties only)",
        "operationId": "getDsp20251Negotiations",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found (also returned for negotiations you are not a party to).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/negotiations/{pid}/agreement/verification": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `ContractAgreementVerificationMessage`",
        "operationId": "postDsp20251NegotiationsAgreementVerification",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/negotiations/{pid}/events": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `ContractNegotiationEventMessage (ACCEPTED only)`",
        "operationId": "postDsp20251NegotiationsEvents",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/negotiations/{pid}/request": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `ContractRequestMessage (counter-request)`",
        "operationId": "postDsp20251NegotiationsRequest",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/negotiations/{pid}/termination": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `ContractNegotiationTerminationMessage`",
        "operationId": "postDsp20251NegotiationsTermination",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/transfers/request": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — request a transfer (`TransferRequestMessage`, `HttpData-PULL`)",
        "operationId": "postDsp20251TransfersRequest",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same `Idempotency-Key` resent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "201": {
            "description": "`TransferProcess` started.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Agreement or consent check failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agreement not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/dsp/2025-1/transfers/{pid}": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Dataspace Protocol 2025-1 — transfer process state (`TransferProcess`, parties only)",
        "operationId": "getDsp20251Transfers",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found (also for transfers you are not a party to).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/transfers/{pid}/completion": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `TransferCompletionMessage`",
        "operationId": "postDsp20251TransfersCompletion",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/transfers/{pid}/edr": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Dataspace Protocol 2025-1 — data address of a started transfer (`TransferStartMessage`, 5-minute token, `no-store`)",
        "operationId": "getDsp20251TransfersEdr",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Agreement or consent no longer valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Transfer is not started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/transfers/{pid}/start": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `TransferStartMessage (resume)`",
        "operationId": "postDsp20251TransfersStart",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/transfers/{pid}/suspension": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `TransferSuspensionMessage`",
        "operationId": "postDsp20251TransfersSuspension",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/transfers/{pid}/termination": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `TransferTerminationMessage`",
        "operationId": "postDsp20251TransfersTermination",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dsp/2025-1/transfers/{pid}/usage-report": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Dataspace Protocol 2025-1 — consumer message `ogq:UsageReportMessage`",
        "operationId": "postDsp20251TransfersUsageReport",
        "tags": ["Dataspace Protocol"],
        "security": [
          {
            "partnerApiKey": []
          },
          {
            "dspRequestProof": []
          },
          {
            "dcpSelfIssuedIdToken": []
          }
        ],
        "parameters": [
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Required by the Dataspace Protocol binding. Resending the same key returns the same process.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DspMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed message or missing `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Signer or participant mismatch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such process (or not a party).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Invalid state transition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/exchange/bithumb-rwa/list": {
      "post": {
        "summary": "Request an IP token listing on the Bithumb RWA board (record only)",
        "operationId": "postV1ExchangeBithumbRwaList",
        "tags": ["Exchange"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tokenId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "initialOfferingSize": {
                    "type": "string",
                    "minLength": 1
                  },
                  "pricePerTokenUsdMicros": {
                    "type": "number"
                  },
                  "settlementCurrency": {
                    "type": "string",
                    "minLength": 1
                  },
                  "kycRequired": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "tokenId",
                  "initialOfferingSize",
                  "pricePerTokenUsdMicros",
                  "settlementCurrency"
                ]
              }
            }
          },
          "x-ogq-zod-schema": "BITHUMB_RWA_LIST_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accepted": {
                      "type": "boolean"
                    },
                    "venue": {
                      "type": "string"
                    },
                    "tokenId": {},
                    "status": {
                      "type": "string"
                    },
                    "connectivityFeePercent": {
                      "type": "number"
                    },
                    "estimatedReviewDays": {
                      "type": "number"
                    },
                    "note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/exchange/sto/register": {
      "post": {
        "summary": "Register an IP token as a security token offering (record only)",
        "operationId": "postV1ExchangeStoRegister",
        "tags": ["Exchange"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tokenId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "issuerLegalName": {
                    "type": "string",
                    "minLength": 1
                  },
                  "issuerBusinessNumber": {
                    "type": "string",
                    "minLength": 1
                  },
                  "trustee": {
                    "type": "string",
                    "minLength": 1
                  },
                  "custodian": {
                    "type": "string",
                    "minLength": 1
                  },
                  "investorType": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "tokenId",
                  "issuerLegalName",
                  "issuerBusinessNumber",
                  "trustee",
                  "custodian",
                  "investorType"
                ]
              }
            }
          },
          "x-ogq-zod-schema": "STO_REGISTER_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accepted": {
                      "type": "boolean"
                    },
                    "venue": {
                      "type": "string"
                    },
                    "tokenId": {},
                    "status": {
                      "type": "string"
                    },
                    "connectivityFeePercent": {
                      "type": "number"
                    },
                    "regulatoryPath": {
                      "type": "string"
                    },
                    "note": {
                      "type": "string"
                    },
                    "requiredNextSteps": {
                      "type": "array"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/ip": {
      "get": {
        "summary": "List IP content",
        "operationId": "listIp",
        "tags": ["IP"],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE · market service unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "partnerApiKey": []
          }
        ]
      }
    },
    "/ip/{id}": {
      "get": {
        "summary": "Get IP detail (DCAT-AP JSON-LD)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "IP detail with DCAT-AP context"
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE · market service unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "partnerApiKey": []
          }
        ]
      },
      "post": {
        "summary": "Purchase an IP item — not available (always 501)",
        "description": "Not provided yet. The purchase delegation had no receiving endpoint in the market service, so this operation never completed a purchase. It now always answers 501 `NOT_IMPLEMENTED` without reading the body or charging anything. Do not call it; the live purchase flow for partners is the order API (`POST /api/v1/orders`).",
        "operationId": "postV1Ip",
        "deprecated": true,
        "tags": ["IP"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "501": {
            "description": "NOT_IMPLEMENTED — this endpoint is not available yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/offers": {
      "get": {
        "summary": "Standing offers (bundle contracts) addressed to this partner",
        "operationId": "listOffers",
        "tags": ["Orders"],
        "description": "Contracts whose counterparty DID is this partner’s, in `active` state. Offers are written by OGQ admin; a partner reads them and orders against them, and cannot write its own terms. The response also carries, per jurisdiction, the legal acknowledgements an order must send and the duties that come with a release — without those an item is excluded as `legal_ack_missing` and the partner cannot tell why. The creator revenue share stored on the contract is deliberately not returned.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "offers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Offer"
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "jurisdictions": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/JurisdictionHint"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "409": {
            "description": "partner_not_onboarded — the partner has no onboarding record with a DID and a named contact, so identity assurance and the contract counterparty cannot be checked"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/orders": {
      "post": {
        "summary": "Order a bundle against an offer",
        "operationId": "createOrder",
        "tags": ["Orders"],
        "description": "Selects content by category (or by explicit ids) inside the scope of an offer, and runs the export gate on every item. A blocked item does not fail the order: it comes back in `excluded[]` with a reason code, using the same vocabulary as the catalogue. Send `Idempotency-Key`; resending it returns the same `orderId` without expanding further. One call expands at most 200 items — continue with `/orders/{id}/expand`.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Unique per partner. A resend returns the original order instead of creating a second one. Falls back to the body field `clientRef`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same Idempotency-Key replayed — the original order, not expanded again",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderPage"
                }
              }
            }
          },
          "201": {
            "description": "Order created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderPage"
                }
              }
            }
          },
          "400": {
            "description": "offer_required, selection_required, kind_required, purpose_invalid, selection_too_large, purpose_mismatch, kind_outside_offer, genre_outside_offer, theme_outside_offer, or invalid_json. The three `*_outside_offer` codes mean the selection asked for a kind, genre or theme the offer does not cover — all three axes of the offer's `bundle` are enforced."
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "404": {
            "description": "offer_not_found — no such offer, or it is not addressed to this partner (404 rather than 403, so the existence of another partner’s contract is not disclosed)"
          },
          "409": {
            "description": "partner_not_onboarded — the partner has no onboarding record with a DID and a named contact, so identity assurance and the contract counterparty cannot be checked"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/orders/{id}": {
      "get": {
        "summary": "Order totals and why items were excluded",
        "operationId": "getOrder",
        "tags": ["Orders"],
        "description": "Counts rather than the item list: how many were accepted, and how many were excluded for each reason. Another partner’s order is 404, not 403.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderSummary"
                }
              }
            }
          },
          "400": {
            "description": "invalid_id — the order id is empty or longer than 64 characters"
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "404": {
            "description": "order_not_found"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/orders/{id}/expand": {
      "post": {
        "summary": "Expand the next page of an order",
        "operationId": "expandOrder",
        "tags": ["Orders"],
        "description": "Continues the selection from the stored keyset cursor (or the one you pass). A category can hold tens of thousands of items and the six gate checks run per item, so an order is filled 200 at a time. The cursor is `(created_at, id)`, so pages never repeat or skip an item even while new content is being registered — the item count is the invoice line count.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cursor": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional. Omit to continue from the cursor stored on the order."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderPage"
                }
              }
            }
          },
          "400": {
            "description": "invalid_id — the order id is empty or longer than 64 characters"
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "404": {
            "description": "order_not_found"
          },
          "409": {
            "description": "offer_not_active — the contract is no longer active or its term has ended, so nothing more can be added; items already accepted stay. Or partner_not_onboarded — the partner's onboarding record no longer carries a DID and a named contact. The body's `code` says which."
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/orders/{id}/manifest": {
      "get": {
        "summary": "List what to fetch for the released items",
        "operationId": "getOrderManifest",
        "tags": ["Orders"],
        "description": "One page of released items with everything needed to take them: a signed data URL (TTL 3600s), the transfer credential (VC 2.0 id + SD-JWT), the identifiers (UCI, SynthID, content hash), the AI label credential id and the conditions (license model, duties, report due date). The URL is signed again on every call rather than stored, so if it expires while you are fetching, just request the same manifest page again. `cursor` is the item table's `(created_at, id)` keyset — pages never repeat or skip an item.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Continue from a previous page. Omit for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["json", "jsonl"],
              "default": "json"
            },
            "description": "`jsonl` streams one item per line; the next cursor comes back in the `X-Next-Cursor` header (empty on the last page)."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderManifestPage"
                }
              },
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "One ManifestItem per line."
                }
              }
            }
          },
          "400": {
            "description": "invalid_id or format_invalid"
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "404": {
            "description": "order_not_found"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/orders/{id}/release": {
      "post": {
        "summary": "Release the accepted items of an order",
        "operationId": "releaseOrder",
        "tags": ["Orders"],
        "description": "Runs the same release procedure as a single transfer for every accepted item: issue the transfer credential, sign the data URL, move the transfer to `released` and write one provenance line. Nothing about a bundle takes a different path, so SynthID, UCI, the ODRL copy and the usage-report duty follow the bundle too. At most 200 items per call — call it again while `remaining > 0`. An item that already went out is replayed, not re-issued, and a single failure does not stop the rest (it is returned in `failed[]` with a reason).",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderReleaseResult"
                }
              }
            }
          },
          "400": {
            "description": "invalid_id — the order id is empty or longer than 64 characters"
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "404": {
            "description": "order_not_found — another partner's order is reported the same way as one that does not exist"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/orders/{id}/usage": {
      "post": {
        "summary": "Report usage for many items of one order",
        "operationId": "reportOrderUsage",
        "tags": ["Orders"],
        "description": "Fans one report out over the items of an order. Calling the per-transfer endpoint thousands of times would make reporting impossible, so the item list is sent once and each item runs through the same validation and recording as the single-transfer endpoint. Items are named by `transferId` or `contentId`; anything that is not an accepted item of this order comes back in `notFound[]` and is not recorded. Re-sending the same body is deduplicated by report hash. Territory, action and cadence violations are recorded and alerted, not rejected — refusing them would leave the fact only on your side. For a flat-period bundle these counts are what the period fee is split by, so an item with no report gets an equal share, never nothing.",
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderUsageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderUsageResult"
                }
              }
            }
          },
          "400": {
            "description": "invalid_id, items_required, items_too_large, invalid_json, or a usage-report format error (invalid_usage_type, invalid_period_start, invalid_usage_count, period_reversed, period_too_long, invalid_action, invalid_territory). One malformed item makes the whole request a format error — nothing is recorded, so you never have to guess which half went in."
          },
          "401": {
            "description": "MISSING_API_KEY or INVALID_API_KEY"
          },
          "404": {
            "description": "order_not_found"
          },
          "503": {
            "description": "AUTH_UNAVAILABLE"
          }
        }
      }
    },
    "/partner/amazon": {
      "post": {
        "summary": "Publish a content item to Amazon (SP-API)",
        "operationId": "postV1PartnerAmazon",
        "tags": ["Channel integrations"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "amazonCategoryId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "marketplace": {
                    "type": "string",
                    "enum": ["US", "JP", "DE"]
                  }
                },
                "required": ["contentId", "amazonCategoryId"]
              }
            }
          },
          "x-ogq-zod-schema": "AMAZON_LISTING_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "contentId": {},
                    "amazonProduct": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream service failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/partner/naver": {
      "post": {
        "summary": "Publish a content item to Naver Smart Store",
        "operationId": "postV1PartnerNaver",
        "tags": ["Channel integrations"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "naverCategoryId": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": ["contentId", "naverCategoryId"]
              }
            }
          },
          "x-ogq-zod-schema": "NAVER_LISTING_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {},
                    "contentId": {},
                    "naverProduct": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/partner/telegram/sticker-sync": {
      "post": {
        "summary": "Sync a purchased OGQ sticker pack to a Telegram sticker set",
        "operationId": "postV1PartnerTelegramStickerSync",
        "tags": ["Channel integrations"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "TELEGRAM_STICKER_SYNC_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "telegramUserId": {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "stickerPackId": {
                    "type": "string",
                    "maxLength": 128
                  }
                },
                "required": ["userId", "telegramUserId", "stickerPackId"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queued": {
                      "type": "boolean"
                    },
                    "stickerPackId": {},
                    "telegramUserId": {},
                    "note": {
                      "type": "string"
                    },
                    "pack": {
                      "type": "object"
                    },
                    "stickerCount": {
                      "type": "integer"
                    },
                    "success": {
                      "type": "boolean"
                    },
                    "setName": {},
                    "inviteUrl": {},
                    "uploaded": {},
                    "skipped": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request. IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Upstream service failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/search/similar": {
      "post": {
        "summary": "Content hash lookup — exact SHA-256 matches only (visual similarity not supported yet; no credits)",
        "operationId": "postV1SearchSimilar",
        "tags": ["Search"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "imageUrl": {
                    "type": "string"
                  },
                  "contentHash": {
                    "type": "string"
                  },
                  "limit": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "x-ogq-zod-schema": "VISION_SIMILAR_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "object"
                    },
                    "capability": {
                      "type": "string",
                      "enum": ["exact_match_only"]
                    },
                    "reason": {
                      "type": "string",
                      "enum": ["PERCEPTUAL_INDEX_NOT_AVAILABLE"]
                    },
                    "similaritySupported": {
                      "type": "boolean",
                      "const": false
                    },
                    "message": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "thumbnailUrl": {
                            "type": "string"
                          },
                          "match": {
                            "type": "string",
                            "enum": ["exact_content_hash"]
                          }
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "creditsUsed": {
                      "type": "integer",
                      "const": 0
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "QUERY_REQUIRED (neither imageUrl nor contentHash) · INVALID_CONTENT_HASH (not a 64-char SHA-256 hex) · Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ],
        "description": "Visual similarity search is not available: there is no perceptual-hash index of registered content, and a SHA-256 `contentHash` cannot be compared by Hamming distance. This endpoint therefore returns only public content registered with the **same** SHA-256 `contentHash` (64 hex chars). `imageUrl` is accepted but not downloaded or analysed (0 results). No credits are charged and nothing is written to the usage ledger or monthly quota. The response states this with `capability: \"exact_match_only\"`, `reason: \"PERCEPTUAL_INDEX_NOT_AVAILABLE\"` and `similaritySupported: false`; an empty result does not mean no similar content exists."
      }
    },
    "/synthid/anchor-status": {
      "get": {
        "summary": "OGQ Synth ID — anchoring status of a registration history",
        "operationId": "getV1SynthidAnchorStatus",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "synthId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "synthId": {},
                    "found": {
                      "type": "boolean"
                    },
                    "anchored": {},
                    "status": {},
                    "reason": {},
                    "ledger": {},
                    "batch": {},
                    "tamperCheck": {},
                    "chain": {},
                    "tier": {},
                    "credits_used": {},
                    "usageRecorded": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "MISSING_SYNTH_ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "ANCHOR_STATUS_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/batch": {
      "post": {
        "summary": "OGQ Synth ID — bulk registration (up to 1,000 items per request)",
        "operationId": "postV1SynthidBatch",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "minItems": 1,
                    "maxItems": 1000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "contentHash": {
                          "type": "string"
                        },
                        "ipType": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "creatorId": {
                          "type": "string"
                        }
                      },
                      "required": ["contentHash"]
                    }
                  }
                },
                "required": ["items"]
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_BATCH_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "batchId": {},
                    "total": {
                      "type": "integer"
                    },
                    "registered": {},
                    "failed": {},
                    "results": {},
                    "tier": {},
                    "remainingQuota": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/batch-file": {
      "post": {
        "summary": "OGQ Synth ID — bulk registration from one CSV or ZIP file",
        "operationId": "postV1SynthidBatchFile",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "archive": {
                    "type": "string",
                    "format": "binary"
                  },
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "batchId": {},
                    "source": {},
                    "total": {
                      "type": "integer"
                    },
                    "registered": {},
                    "failed": {},
                    "skipped": {},
                    "parseErrors": {},
                    "results": {},
                    "tier": {},
                    "creditsUsed": {},
                    "usageRecorded": {},
                    "remainingQuota": {},
                    "elapsedMs": {},
                    "limits": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "FILE_REQUIRED · NO_SUPPORTED_ENTRIES · NO_VALID_ROWS · ROW_LIMIT_EXCEEDED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "FILE_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "BATCH_FILE_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/buyer-watermark": {
      "post": {
        "summary": "OGQ Synth ID — create a per-buyer fingerprint",
        "operationId": "postV1SynthidBuyerWatermark",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "BUYER_WATERMARK_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentId": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "buyerId": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "purchaseId": {
                    "type": "string",
                    "maxLength": 200
                  }
                },
                "required": ["contentId", "buyerId", "purchaseId"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fingerprint": {},
                    "buyerId": {},
                    "contentId": {},
                    "purchaseId": {},
                    "registryId": {},
                    "registered": {},
                    "registryError": {},
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ID_TOO_LONG. IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "BUYER_WATERMARK_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/crawl": {
      "post": {
        "summary": "OGQ Synth ID — on-demand misuse scan for one registration (charges credits)",
        "operationId": "postV1SynthidCrawl",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "synthId": {
                    "type": "string"
                  },
                  "contentHash": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_CRAWL_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "synthId": {},
                    "content_hash": {},
                    "findings": {},
                    "findings_count": {
                      "type": "integer"
                    },
                    "scanned_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "coverage": {
                      "type": "object"
                    },
                    "credits_used": {},
                    "usageRecorded": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/detect": {
      "post": {
        "summary": "OGQ Synth ID — detect a watermark in an uploaded file (charges credits)",
        "operationId": "postV1SynthidDetect",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "format": "binary"
                  },
                  "content_type": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "DETECT_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/dmca": {
      "post": {
        "summary": "OGQ Synth ID — generate a DMCA takedown notice",
        "operationId": "postV1SynthidDmca",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "DMCA_NOTICE_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "synthId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "violationUrl": {
                    "type": "string",
                    "maxLength": 2048
                  },
                  "reporterEmail": {
                    "type": "string",
                    "maxLength": 320
                  }
                },
                "required": ["synthId", "violationUrl", "reporterEmail"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "dmcaId": {},
                    "notice_text": {},
                    "status": {
                      "type": "string"
                    },
                    "synthId": {},
                    "violationUrl": {},
                    "generated_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "DMCA_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/embed": {
      "post": {
        "summary": "OGQ Synth ID — embed a watermark into an uploaded file",
        "operationId": "postV1SynthidEmbed",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "format": "binary"
                  },
                  "content_type": {
                    "type": "string"
                  },
                  "creator_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ogq_synthid": {},
                    "watermark_type": {},
                    "watermark_methods": {},
                    "original_hash": {},
                    "uci_code": {},
                    "content_type": {},
                    "watermarked_content": {},
                    "registered_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "registered": {},
                    "provenance_logged": {},
                    "degraded": {},
                    "registry_error": {},
                    "provenance_error": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/extract": {
      "post": {
        "summary": "OGQ Synth ID — extract a watermark from content (charges credits)",
        "operationId": "postV1SynthidExtract",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1
                  },
                  "content": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": ["type", "content"]
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_EXTRACT_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "found": {},
                    "type": {},
                    "extracted": {},
                    "method": {},
                    "creditsUsed": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/generate": {
      "post": {
        "summary": "OGQ Synth ID — generate and register an identifier (charges credits)",
        "operationId": "postV1SynthidGenerate",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentHash": {
                    "type": "string",
                    "minLength": 1
                  },
                  "ipType": {
                    "type": "string",
                    "minLength": 1
                  },
                  "creatorId": {
                    "type": "string"
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  }
                },
                "required": ["contentHash", "ipType"]
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_GENERATE_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "synthId": {},
                    "type": {},
                    "contentHash": {},
                    "creatorHash": {},
                    "timestamp": {},
                    "hmac": {},
                    "creditsUsed": {},
                    "registered": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "REGISTRY_WRITE_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/health": {
      "get": {
        "summary": "OGQ Synth ID gateway health",
        "operationId": "synthIdHealth",
        "tags": ["SynthID"],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/synthid/infringement-scan": {
      "post": {
        "summary": "OGQ Synth ID — rights infringement scan (charges credits)",
        "operationId": "postV1SynthidInfringementScan",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentId": {
                    "type": "string",
                    "minLength": 1
                  },
                  "scanType": {
                    "type": "string"
                  }
                },
                "required": ["contentId"]
              }
            }
          },
          "x-ogq-zod-schema": "INFRINGEMENT_SCAN_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "scanId": {},
                    "contentId": {},
                    "scanType": {},
                    "findings": {},
                    "findings_count": {
                      "type": "integer"
                    },
                    "infringing_count": {
                      "type": "integer"
                    },
                    "dmca_notices_generated": {},
                    "credits_used": {},
                    "scanned_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/monitor": {
      "get": {
        "summary": "OGQ Synth ID — misuse monitoring findings and real coverage",
        "operationId": "getV1SynthidMonitor",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "synthId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partner_scope": {
                      "type": "boolean"
                    },
                    "findings": {},
                    "findings_count": {
                      "type": "integer"
                    },
                    "scans": {
                      "type": "object"
                    },
                    "coverage": {
                      "type": "object"
                    },
                    "webhook": {
                      "type": "object"
                    },
                    "tier": {},
                    "credits_used": {},
                    "usageRecorded": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "MONITOR_LOOKUP_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/monitor/webhook": {
      "get": {
        "summary": "OGQ Synth ID — read the monitoring webhook setting",
        "operationId": "getV1SynthidMonitorWebhook",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "registered": {},
                    "webhookId": {},
                    "updatedAt": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "WEBHOOK_LOOKUP_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "OGQ Synth ID — set the monitoring webhook (the signing secret is shown once)",
        "operationId": "postV1SynthidMonitorWebhook",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "test",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "status": {
                    "type": "string",
                    "enum": ["active", "disabled"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhookId": {},
                    "status": {},
                    "secret": {},
                    "signature": {
                      "type": "object"
                    },
                    "testDelivery": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "BAD_BODY · INVALID_WEBHOOK_URL · WEBHOOK_URL_NOT_ALLOWED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "WEBHOOK_REGISTER_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/report": {
      "get": {
        "summary": "OGQ Synth ID — forensic report for one identifier",
        "operationId": "getV1SynthidReport",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "synthId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "INVALID_SYNTHID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "REPORT_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/similar": {
      "post": {
        "summary": "OGQ Synth ID — similar content search (aHash; reports capability honestly)",
        "operationId": "postV1SynthidSimilar",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "aHash": {
                    "type": "string"
                  },
                  "threshold": {
                    "anyOf": [
                      {
                        "anyOf": [
                          {
                            "type": "number"
                          },
                          {
                            "type": "string"
                          }
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_SIMILAR_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "query": {
                      "type": "object"
                    },
                    "capability": {},
                    "reason": {},
                    "message": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array"
                    },
                    "count": {
                      "type": "number"
                    },
                    "creditsUsed": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_json · INVALID_JSON · INVALID_AHASH · INVALID_THRESHOLD · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/subscribe": {
      "get": {
        "summary": "OGQ Synth ID — current subscription tier and quota",
        "operationId": "getV1SynthidSubscribe",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partnerId": {},
                    "tier": {},
                    "monthlyLimit": {},
                    "monthlyPrice": {},
                    "currentMonthUsage": {},
                    "remainingQuota": {},
                    "usageUnavailable": {},
                    "quotaUnit": {
                      "type": "string"
                    },
                    "creditsPerCall": {},
                    "paidTierBillingStatus": {
                      "type": "string"
                    },
                    "selfServiceTiers": {},
                    "tiers": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "OGQ Synth ID — change subscription tier",
        "operationId": "postV1SynthidSubscribe",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tier": {
                    "type": "string"
                  }
                },
                "required": ["tier"]
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_SUBSCRIBE_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partnerId": {},
                    "tier": {},
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "TIER_BILLING_NOT_AVAILABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "TIER_UPDATE_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/usage": {
      "get": {
        "summary": "OGQ Synth ID — usage and billing summary",
        "operationId": "getV1SynthidUsage",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partnerId": {},
                    "total": {},
                    "thisMonth": {},
                    "daily": {},
                    "pricing": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/synthid/verify": {
      "post": {
        "summary": "OGQ Synth ID — verify an identifier or content hash (charges credits)",
        "operationId": "postV1SynthidVerify",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "synthId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "contentHash": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_VERIFY_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "INVALID_JSON · INVALID_SYNTHID · INVALID_CONTENT_HASH · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "VERIFY_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/synthid/watermark": {
      "post": {
        "summary": "OGQ Synth ID — watermark content (charges credits)",
        "operationId": "postV1SynthidWatermark",
        "tags": ["OGQ Synth ID"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "minLength": 1
                  },
                  "content": {
                    "type": "string",
                    "minLength": 1
                  },
                  "synthId": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": ["type", "content"]
              }
            }
          },
          "x-ogq-zod-schema": "SYNTHID_WATERMARK_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "type": {},
                    "watermarked": {},
                    "watermarkMethod": {},
                    "content": {},
                    "synthId": {},
                    "creditsUsed": {},
                    "registered": {},
                    "registryError": {},
                    "note": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Quota exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/uci/issue": {
      "post": {
        "summary": "Issue a UCI (Korea Copyright Commission identifier; charges credits)",
        "operationId": "postV1UciIssue",
        "tags": ["UCI"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ip_content_id": {
                    "type": "string",
                    "minLength": 1
                  },
                  "content_type": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "title": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "creator_name": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "content_hash": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ogq_content_id": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": ["ip_content_id"]
              }
            }
          },
          "x-ogq-zod-schema": "UCI_ISSUE_SCHEMA"
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uci_code": {},
                    "issued_at": {},
                    "certificate_url": {},
                    "issuer": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "source": {},
                    "credits_used": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request · IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/usage/attestation": {
      "post": {
        "summary": "Issue an AI usage attestation credential (W3C VC)",
        "operationId": "postV1UsageAttestation",
        "tags": ["Usage"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "USAGE_ATTESTATION_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contentId": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "consumerId": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "consumerName": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "purpose": {
                    "type": "string",
                    "enum": ["training", "generation", "exposure"]
                  },
                  "model": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "usageSummary": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "maxLength": 100
                      },
                      "unit": {
                        "type": "string",
                        "maxLength": 100
                      },
                      "count": {
                        "type": "number"
                      }
                    },
                    "required": ["type", "unit", "count"]
                  },
                  "period": {
                    "type": "object",
                    "properties": {
                      "from": {
                        "type": "string",
                        "maxLength": 40
                      },
                      "to": {
                        "type": "string",
                        "maxLength": 40
                      }
                    },
                    "required": ["from", "to"]
                  },
                  "rightsBasis": {
                    "type": "string",
                    "enum": ["license", "fair-use", "public-domain", "opt-in"]
                  }
                },
                "required": [
                  "contentId",
                  "consumerId",
                  "consumerName",
                  "purpose",
                  "usageSummary",
                  "period"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "vcId": {},
                    "vcPayload": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "ATTESTATION_PERSIST_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/usage/report": {
      "post": {
        "summary": "Bulk usage report for AI training, generation and exposure",
        "operationId": "postV1UsageReport",
        "tags": ["Usage"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "x-ogq-zod-schema": "USAGE_REPORT_SCHEMA",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "billingPeriod": {
                    "type": "string",
                    "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
                  },
                  "items": {
                    "minItems": 1,
                    "maxItems": 100000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {}
                    }
                  }
                },
                "required": ["billingPeriod", "items"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_KEY_INVALID · INVALID_JSON · VALIDATION_FAILED (`issues[]` lists the failing field paths and rule names; values are never echoed).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED (same key, different body) · IDEMPOTENCY_REQUEST_IN_PROGRESS (`Retry-After: 1`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "INGEST_FAILED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE (key store) · IDEMPOTENCY_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "8–128 characters of `A-Z a-z 0-9 . _ : -`. The same key with the same body replays the first 2xx response (`Idempotent-Replayed: true`) without doing the work again; the same key with a different body returns 409 `IDEMPOTENCY_KEY_REUSED`. Without a key every call is processed.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            }
          }
        ]
      }
    },
    "/usage/rate-plans": {
      "get": {
        "summary": "Read your own usage rate plans",
        "description": "Returns the usage rate plans signed with the calling partner. `consumerId` must be the partner of the key — any other value answers 404 (another partner's plans are never shown, nor whether they exist).",
        "operationId": "getV1UsageRatePlans",
        "tags": ["Usage"],
        "security": [{ "partnerApiKey": [] }, { "ogqAdminSession": [] }],
        "parameters": [
          { "name": "consumerId", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "consumerId": { "type": "string" },
                    "count": { "type": "integer" },
                    "plans": { "type": "array", "items": { "type": "object" } }
                  }
                }
              }
            }
          },
          "400": {
            "description": "consumerId required.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "404": {
            "description": "Not your consumer id.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "502": {
            "description": "AUTH_CHECK_FAILED — the admin session could not be judged (fail-closed).",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/v2/webhooks/register": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "List the caller's webhooks",
        "operationId": "getV2WebhooksRegister",
        "tags": ["Webhooks"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhooks": {},
                    "count": {
                      "type": "integer"
                    },
                    "delivery": {},
                    "deliveries": {},
                    "error": {},
                    "code": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "WEBHOOK_REGISTRY_UNAVAILABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Register a webhook (the signing secret is shown once)",
        "operationId": "postV2WebhooksRegister",
        "tags": ["Webhooks"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url", "events"],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhook": {},
                    "secret": {},
                    "secretAtRest": {},
                    "secretNotice": {
                      "type": "string"
                    },
                    "signature": {
                      "type": "object"
                    },
                    "delivery": {},
                    "error": {},
                    "code": {}
                  }
                }
              }
            }
          },
          "201": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhook": {},
                    "secret": {},
                    "secretAtRest": {},
                    "secretNotice": {
                      "type": "string"
                    },
                    "signature": {
                      "type": "object"
                    },
                    "delivery": {},
                    "error": {},
                    "code": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "INVALID_JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "WEBHOOK_REGISTRY_UNAVAILABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Revoke a webhook",
        "operationId": "deleteV2WebhooksRegister",
        "tags": ["Webhooks"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhook": {},
                    "delivery": {},
                    "error": {},
                    "code": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "WEBHOOK_REGISTRY_UNAVAILABLE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v2/webhooks/register/preview": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Preview a signed webhook event, or queue it for redelivery (nothing is sent while the delivery switch is off)",
        "operationId": "postV2WebhooksRegisterPreview",
        "tags": ["Webhooks"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["webhookId"],
                "properties": {
                  "webhookId": {
                    "type": "string"
                  },
                  "eventType": {
                    "type": "string"
                  },
                  "send": {
                    "type": "boolean"
                  },
                  "queue": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requested": {
                      "type": "boolean"
                    },
                    "preview": {},
                    "error": {},
                    "code": {}
                  }
                }
              }
            }
          },
          "202": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "requested": {
                      "type": "boolean"
                    },
                    "preview": {},
                    "error": {},
                    "code": {},
                    "queued": {
                      "type": "integer"
                    },
                    "eventId": {
                      "type": "string"
                    },
                    "deliveryId": {},
                    "delivery": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "WEBHOOK_ID_INVALID · WEBHOOK_EVENT_INVALID · WEBHOOK_EVENT_NOT_SUBSCRIBED · INVALID_JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "WEBHOOK_DELIVERY_DISABLED",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "WEBHOOK_REGISTRY_UNAVAILABLE · WEBHOOK_QUEUE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later) · RECONCILE_REDELIVERY_TABLES_NOT_PROVISIONED — the redelivery queue is not set up in this environment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/partner-disputes": {
      "get": {
        "summary": "List clearing disputes filed by, or involving, the calling partner",
        "operationId": "getV1ClearingPartnerDisputes",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later), or CLEARING_DISPUTE_TABLES_NOT_PROVISIONED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "File a clearing dispute on a DSP agreement as its consumer partner (no money moves)",
        "operationId": "postV1ClearingPartnerDisputes",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["targetId", "reasonCode", "description"],
                "properties": {
                  "targetKind": {
                    "type": "string",
                    "description": "Only `dsp_agreement`."
                  },
                  "targetId": {
                    "type": "string",
                    "description": "DSP agreement id (urn:uuid:…)."
                  },
                  "reasonCode": {
                    "type": "string",
                    "description": "usage_violation · unauthorized_use · rights_infringement · record_mismatch · delivery_failure · quality_issue · other"
                  },
                  "description": {
                    "type": "string",
                    "description": "10–2000 characters."
                  },
                  "attachmentHashes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Up to 5 SHA-256 fingerprints (`sha256:<64 hex>`). Files are never uploaded."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same key and same content — the original filing is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "replayed": {},
                    "dispute": {}
                  }
                }
              }
            }
          },
          "201": {
            "description": "Filed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "replayed": {},
                    "dispute": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "IDEMPOTENCY_KEY_REQUIRED (header `Idempotency-Key`) · BODY_INVALID · field errors",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "DISPUTE_TARGET_NOT_FOUND — no such agreement, or the key is not its consumer partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED · DISPUTE_WINDOW_CLOSED · DISPUTE_ALREADY_OPEN",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "DISPUTE_RATE_LIMITED — 5 filings per 24 hours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later), or CLEARING_DISPUTE_TABLES_NOT_PROVISIONED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/partner-disputes/{id}": {
      "get": {
        "summary": "Read one clearing dispute the calling partner filed or is a party to",
        "operationId": "getV1ClearingPartnerDisputesById",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "dispute": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "DISPUTE_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later), or CLEARING_DISPUTE_TABLES_NOT_PROVISIONED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/partner-disputes/{id}/withdraw": {
      "post": {
        "summary": "Withdraw a clearing dispute the calling partner filed (before a decision)",
        "operationId": "postV1ClearingPartnerDisputesWithdraw",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Withdrawn.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "dispute": {},
                    "clearingRecorded": {}
                  }
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "DISPUTE_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "DISPUTE_CLOSED · DISPUTE_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later), or CLEARING_DISPUTE_TABLES_NOT_PROVISIONED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/clearing/partner-disputes/{id}/responses": {
      "post": {
        "summary": "Submit the consumer partner's response to a dispute filed by another party",
        "operationId": "postV1ClearingPartnerDisputesResponses",
        "tags": ["Clearing"],
        "security": [
          {
            "partnerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["text"],
                "properties": {
                  "text": {
                    "type": "string",
                    "description": "10–2000 characters."
                  },
                  "attachmentHashes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Up to 5 SHA-256 fingerprints (`sha256:<64 hex>`)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Same response resent — no new record.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "replayed": {},
                    "dispute": {}
                  }
                }
              }
            }
          },
          "201": {
            "description": "Response recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "replayed": {},
                    "dispute": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "BODY_INVALID · RESPONSE_LENGTH · ATTACHMENTS_INVALID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "MISSING_API_KEY · INVALID_API_KEY · API_KEY_EXPIRED — the partner key is missing, unknown or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "DISPUTE_NOT_FOUND",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "DISPUTE_RESPONSE_BY_FILER · DISPUTE_CLOSED · DISPUTE_RESPONSE_LIMIT · DISPUTE_CONFLICT",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "PAYLOAD_TOO_LARGE",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "AUTH_UNAVAILABLE — the key store could not be read (retry later), or CLEARING_DISPUTE_TABLES_NOT_PROVISIONED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dataspace/dcp/{slug}/issuer/metadata": {
      "servers": [{ "url": "https://stg.nova.ogq.me/api", "description": "Staging (current)" }],
      "get": {
        "summary": "DCP 1.0 Issuer Service — IssuerMetadata (credentials this data space issues)",
        "operationId": "getDataspaceDcpIssuerMetadata",
        "tags": ["Decentralized Claims Protocol"],
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Issuer data space — only the platform operator `ogq` hosts the Issuer Service.",
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "`IssuerMetadata` — `issuer` (the platform did:web) and `credentialsSupported` (`MembershipCredential`, profile `vc11-sl2021/jwt`, binding `did:web`). Object ids are stable.",
            "content": { "application/json": { "schema": { "type": "object" } } }
          },
          "404": {
            "description": "NOT_FOUND — the Issuer Service is switched off in this environment, or the data space is not the platform operator.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/dataspace/dcp/{slug}/issuer/credentials": {
      "servers": [{ "url": "https://stg.nova.ogq.me/api", "description": "Staging (current)" }],
      "post": {
        "summary": "DCP 1.0 Issuer Service — request credentials (`CredentialRequestMessage`)",
        "description": "Authorization = the holder's self-issued ID token (`Bearer`, iss = sub = holder did:web, aud = the platform DID, key in the holder DID document `capabilityInvocation`, single-use `jti`, 30 s clock skew). Holders = active participant data spaces of this platform, or an allow-listed DID (staging only). On success the credential is signed (ES256, platform `#key-ec`) and delivered to the holder Credential Service Storage API (`POST {CredentialService}/credentials` with a `CredentialMessage`); the holder's `token` claim is echoed in the delivery token. Failed deliveries are retried with exponential backoff (5 attempts). The same `holderPid` from the same holder identifies the same request — it is never issued twice.",
        "operationId": "postDataspaceDcpIssuerCredentials",
        "tags": ["Decentralized Claims Protocol"],
        "security": [{ "dcpHolderIdToken": [] }],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Issuer data space — only the platform operator `ogq` hosts the Issuer Service.",
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["type", "holderPid", "credentials"],
                "properties": {
                  "@context": {},
                  "type": { "const": "CredentialRequestMessage" },
                  "holderPid": { "type": "string", "maxLength": 200 },
                  "credentials": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10,
                    "items": {
                      "type": "object",
                      "required": ["id"],
                      "properties": { "id": { "type": "string" } }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Request accepted — `Location: …/issuer/requests/{id}`." },
          "200": {
            "description": "Same holder and `holderPid` resent — the earlier request (`Location` repeated, no second issuance).",
            "content": { "application/json": { "schema": { "type": "object" } } }
          },
          "413": {
            "description": "BODY_TOO_LARGE — the request body exceeds the limit.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "400": {
            "description": "REQUEST_INVALID · CREDENTIAL_UNSUPPORTED — malformed message, empty `credentials`, missing `holderPid` or an unknown credential object id.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "401": {
            "description": "DCP_TOKEN_INVALID · DCP_TOKEN_EXPIRED · DCP_DID_UNRESOLVABLE · DCP_SIGNATURE_INVALID · DCP_TOKEN_REPLAYED.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "403": {
            "description": "HOLDER_NOT_ALLOWED — the holder is not an active participant (or allow-listed).",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "404": {
            "description": "NOT_FOUND — Issuer Service switched off or not the platform operator.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "503": {
            "description": "DCP_REPLAY_CHECK_UNAVAILABLE · ISSUER_STORE_UNAVAILABLE (retry later).",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/dataspace/dcp/{slug}/issuer/requests/{id}": {
      "servers": [{ "url": "https://stg.nova.ogq.me/api", "description": "Staging (current)" }],
      "get": {
        "summary": "DCP 1.0 Issuer Service — credential request status (`CredentialStatus`)",
        "operationId": "getDataspaceDcpIssuerRequest",
        "tags": ["Decentralized Claims Protocol"],
        "security": [{ "dcpHolderIdToken": [] }],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Issuer data space — only the platform operator `ogq` hosts the Issuer Service.",
            "schema": { "type": "string" }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "`issuerPid` from the `Location` header.",
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "`CredentialStatus` — `status` RECEIVED · ISSUED · REJECTED (only to the holder that made the request).",
            "content": { "application/json": { "schema": { "type": "object" } } }
          },
          "401": {
            "description": "DCP_TOKEN_INVALID · DCP_TOKEN_EXPIRED · DCP_DID_UNRESOLVABLE · DCP_SIGNATURE_INVALID · DCP_TOKEN_REPLAYED.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "503": {
            "description": "DCP_REPLAY_CHECK_UNAVAILABLE · ISSUER_STORE_UNAVAILABLE (retry later).",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "404": {
            "description": "REQUEST_NOT_FOUND — unknown id or another holder's request; NOT_FOUND when the Issuer Service is off.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/rova/jobs": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Create a Rova job — card news / thumbnail / TikTok / banner / slides from a creator character (async)",
        "description": "Checks rights (secondary creation, Rova allowed, commercial use) and queues a job. Rendering runs after the response; poll GET /rova/jobs/{id}. Credits: free-trial credits are used first (charged when the job finishes); otherwise the quoted credits are held when the job is created and the actual AI cost is settled at the end (never above the quote). A failed paid job is refunded in full (status failed_refunded).",
        "operationId": "createRovaJob",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            },
            "description": "Same key + same body replays the first response (Idempotent-Replayed: true); same key + different body is 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "contentId",
                  "format",
                  "preset",
                  "title",
                  "body",
                  "pageCount",
                  "tone",
                  "lang",
                  "consent"
                ],
                "properties": {
                  "contentId": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "format": {
                    "type": "string",
                    "enum": ["cardnews", "thumbnail", "tiktok", "banner", "ppt"]
                  },
                  "preset": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 1500
                  },
                  "pageCount": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10
                  },
                  "withTitlePage": {
                    "type": "boolean"
                  },
                  "tone": {
                    "type": "string",
                    "enum": ["cute", "serious", "humor", "emotional", "info"]
                  },
                  "lang": {
                    "type": "string"
                  },
                  "commercial": {
                    "type": "boolean"
                  },
                  "consent": {
                    "type": "boolean",
                    "const": true
                  },
                  "scene": {
                    "type": "boolean",
                    "description": "Also draw an AI background scene per page in the character's style (path B). Only when the server offers it (quote scene_available). Costs more credits; if the scene fails the original-work review, the job falls back to the original art and the scene is not charged."
                  },
                  "premium": {
                    "type": "boolean",
                    "description": "Legacy alias of grade=plus (kept for old clients). Prefer grade."
                  },
                  "grade": {
                    "type": "string",
                    "enum": ["standard", "plus", "studio"],
                    "description": "Quality grade for AI full-art pages: standard (basic) · plus (AI art director + Gemini Flash Lite image — the 132 level) · studio (AI art director + gpt-image-2.5-sunburst high — the 131 level). Only grades listed in the quote's grades are accepted; otherwise 400 ROVA_GRADE_NOT_AVAILABLE. Omitted = standard (or plus when the legacy premium flag is set)."
                  },
                  "templateId": {
                    "type": ["string", "null"],
                    "format": "uuid",
                    "description": "Layout template chosen from GET /rova/templates/recommend (an abstract composition recipe — badge, headline rows, numbered panels, bubbles, closing band). Omitted or null = Auto (different every time). Must be published and fit this format, page count and size; otherwise 400 ROVA_TEMPLATE_UNAVAILABLE. Does not change the credits. Results still differ between jobs with the same template."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "labeling",
                        "composing",
                        "rendering",
                        "finalizing",
                        "done",
                        "partial",
                        "failed",
                        "failed_refunded"
                      ]
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string",
                      "enum": ["poll", "download", "regenerate"]
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID · IDEMPOTENCY_KEY_REQUIRED · IDEMPOTENCY_KEY_INVALID · ROVA_SCENE_NOT_AVAILABLE (scene art not offered here) · ROVA_GRADE_NOT_AVAILABLE (quality grade not open here or for this user).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "INSUFFICIENT_CREDITS — not enough credits (required · balance in the body). Nothing is created or rendered.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "ROVA_NOT_ALLOWED (creator does not allow it) · ROVA_COMMERCIAL_NOT_ALLOWED · ROVA_SCENE_NOT_ALLOWED (creator does not allow AI scene art) · TERMS_NOT_AGREED (payment terms not agreed — no credits used).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED (feature off) · ROVA_JOB_NOT_FOUND / ROVA_CONTENT_NOT_FOUND — not found or not yours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "IDEMPOTENCY_KEY_REUSED · IDEMPOTENCY_REQUEST_IN_PROGRESS.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — storage or content source unavailable (retry later); CREDIT_SERVICE_UNAVAILABLE — the credit balance could not be checked, so nothing was created; ROVA_SCENE_SOURCE_UNAVAILABLE — the original work's AI permission could not be checked (scene art).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rova/jobs/{id}": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Rova job status and page previews (owner only)",
        "operationId": "getRovaJob",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "labeling",
                        "composing",
                        "rendering",
                        "finalizing",
                        "done",
                        "partial",
                        "failed",
                        "failed_refunded"
                      ]
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string",
                      "enum": ["poll", "download", "regenerate"]
                    },
                    "tool_confidence": {
                      "type": "number"
                    },
                    "format": {
                      "type": "string"
                    },
                    "preset": {
                      "type": "string"
                    },
                    "page_count": {
                      "type": "integer"
                    },
                    "pages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "no": {
                            "type": "integer"
                          },
                          "role": {
                            "type": "string"
                          },
                          "preview_url": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "charged_credits": {
                      "type": "integer"
                    },
                    "free_trial_credits": {
                      "type": "integer"
                    },
                    "refund_credits": {
                      "type": "integer"
                    },
                    "billing": {
                      "type": "string",
                      "enum": ["none", "free", "paid"]
                    },
                    "quote_credits": {
                      "type": "integer"
                    },
                    "error": {
                      "type": ["string", "null"]
                    },
                    "downloads": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "commercial": {
                      "type": "boolean",
                      "description": "Commercial use chosen at creation (allowed only when the source IP permits it) — decides the usage notice."
                    },
                    "grade": {
                      "type": "object",
                      "description": "Quality grade: asked = chosen at creation · used = grade actually drawn with AI full-art (null when the job used the original art) · fallback = drawn one grade lower because the engine was unavailable (the difference was refunded at settlement).",
                      "properties": {
                        "asked": { "type": "string", "enum": ["standard", "plus", "studio"] },
                        "used": { "type": ["string", "null"] },
                        "engine": { "type": ["string", "null"] },
                        "fallback": { "type": "boolean" }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED (feature off) · ROVA_JOB_NOT_FOUND / ROVA_CONTENT_NOT_FOUND — not found or not yours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — storage or content source unavailable (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rova/jobs/{id}/regenerate": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Make a Rova job again (all pages) or redo some pages — creates a new job",
        "operationId": "regenerateRovaJob",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            },
            "description": "Same key + same body replays the first response (Idempotent-Replayed: true); same key + different body is 409."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pages": {
                    "type": "array",
                    "items": {
                      "type": "integer",
                      "minimum": 1
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued (new job).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "labeling",
                        "composing",
                        "rendering",
                        "finalizing",
                        "done",
                        "partial",
                        "failed",
                        "failed_refunded"
                      ]
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string",
                      "enum": ["poll", "download", "regenerate"]
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID · IDEMPOTENCY_KEY_REQUIRED · IDEMPOTENCY_KEY_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "INSUFFICIENT_CREDITS — not enough credits (required · balance in the body). Nothing is created or rendered.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "ROVA_NOT_ALLOWED · ROVA_COMMERCIAL_NOT_ALLOWED · TERMS_NOT_AGREED (payment terms not agreed — no credits used).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED (feature off) · ROVA_JOB_NOT_FOUND / ROVA_CONTENT_NOT_FOUND — not found or not yours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ROVA_JOB_IN_PROGRESS · ROVA_JOB_NOT_DONE · IDEMPOTENCY_KEY_REUSED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — storage or content source unavailable (retry later); CREDIT_SERVICE_UNAVAILABLE — the credit balance could not be checked, so nothing was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rova/jobs/{id}/rate": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "post": {
        "summary": "Rate the layout template of a finished Rova job (I like it / Not for me) — one rating per job",
        "description": "Records one `rated` event for the template the job used (only jobs that picked a layout template; «auto» jobs return 409). A second call returns the first rating unchanged. The rating feeds template ranking (weekly retire of the bottom 10%) and the popularity term of template recommendations. No credits, mail or external calls.",
        "operationId": "rateRovaJob",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            },
            "description": "Same key + same body replays the first response (Idempotent-Replayed: true); same key + different body is 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["value"],
                "properties": {
                  "value": {
                    "type": "string",
                    "enum": ["up", "down"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rated (or already rated — `recorded: false` and the first value).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "template_id": {
                      "type": "string"
                    },
                    "rated": {
                      "type": "string",
                      "enum": ["up", "down"]
                    },
                    "recorded": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string"
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID (value must be up or down) · IDEMPOTENCY_KEY_REQUIRED · IDEMPOTENCY_KEY_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED (feature off) · ROVA_JOB_NOT_FOUND — not found or not yours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ROVA_JOB_NOT_DONE (still running or failed) · ROVA_JOB_NO_TEMPLATE (the job used «auto», nothing to rate) · IDEMPOTENCY_KEY_REUSED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE — the template store is not ready (retry later; the job and its result are unaffected).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rova/jobs/{id}/download": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Download a Rova result — png (one page) · zip · pdf · pptx (slides only), owner only",
        "operationId": "downloadRovaJob",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["png", "zip", "pdf", "pptx"],
              "default": "zip"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "inline",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["1"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File bytes.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/vnd.openxmlformats-officedocument.presentationml.presentation": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "ROVA_FORMAT_UNSUPPORTED · ROVA_INPUT_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_JOB_NOT_FOUND · ROVA_PAGE_NOT_FOUND · ROVA_DISABLED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ROVA_JOB_NOT_DONE — bundles are available once the job is done · ROVA_JOB_FAILED — a failed job has no downloads (make it again).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_FILE_UNAVAILABLE · ROVA_STORE_UNAVAILABLE.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rova/quote": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Rova credit quote (AI cost with the 90% margin pricing — the most a job will charge)",
        "operationId": "quoteRova",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "preset",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pages",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "scene",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "1 = include AI scene art (counted only when scene_available)."
          },
          {
            "name": "premium",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["1"]
            },
            "description": "Legacy: 1 = grade plus."
          },
          {
            "name": "grade",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["standard", "plus", "studio"]
            },
            "description": "Quality grade to price (counted only when listed in grades; omitted = this environment's default_grade)."
          }
        ],
        "responses": {
          "200": {
            "description": "Quote.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "credits": {
                      "type": "integer",
                      "description": "What the user pays for this job: AI generation credits plus the character fee (pricing mode C). Modes A and B: AI generation only."
                    },
                    "ai_credits": {
                      "type": "integer",
                      "description": "AI generation part (cost-based canonical price). Free trial and actual-cost settlement apply to this part only."
                    },
                    "ip_fee_credits": {
                      "type": "integer",
                      "description": "Character fee (pricing mode C only, per page, otherwise 0). Charged as a separate use and shared with the creator."
                    },
                    "pricing_mode": {
                      "type": "string",
                      "enum": ["A", "B", "C"],
                      "description": "Pricing mode stored on the job when it is created."
                    },
                    "cost_usd": {
                      "type": "number"
                    },
                    "charged_now": {
                      "type": "integer"
                    },
                    "scene_available": {
                      "type": "boolean"
                    },
                    "scene": {
                      "type": "boolean"
                    },
                    "fullart": {
                      "type": "boolean",
                      "description": "AI full-art pages (the model draws the whole card, text checked) are this environment's default path for this user (false outside the allowlist)."
                    },
                    "grades": {
                      "type": "array",
                      "description": "Open quality grades with their quote (empty when AI full-art is closed for this user).",
                      "items": {
                        "type": "object",
                        "properties": {
                          "grade": { "type": "string", "enum": ["standard", "plus", "studio"] },
                          "credits": { "type": "integer" },
                          "cost_usd": { "type": "number" }
                        }
                      }
                    },
                    "grade": {
                      "type": "string",
                      "enum": ["standard", "plus", "studio"],
                      "description": "Grade this quote was priced at."
                    },
                    "default_grade": {
                      "type": "string",
                      "enum": ["standard", "plus", "studio"],
                      "description": "Grade the input sheet selects first."
                    },
                    "premium_available": {
                      "type": "boolean",
                      "description": "Legacy: plus is open."
                    },
                    "premium": {
                      "type": "boolean"
                    },
                    "charge_on": {
                      "type": "boolean"
                    },
                    "estimated": {
                      "type": "boolean"
                    },
                    "breakdown": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED (feature off) · ROVA_JOB_NOT_FOUND / ROVA_CONTENT_NOT_FOUND — not found or not yours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — storage or content source unavailable (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rova/templates/recommend": {
      "servers": [{ "url": "https://stg.nova.ogq.me/api", "description": "Staging (current)" }],
      "get": {
        "summary": "Rova layout template suggestions (top 3 abstract composition recipes + Auto)",
        "operationId": "recommendRovaTemplates",
        "tags": ["Rova"],
        "description": "Suggests layout templates that fit the format, size, page count, tone and the shape of the text (list, short, question, numbers, long — the text itself is never sent). Templates are abstract composition recipes (no source posts, URLs, accounts, images or fixed colors). Score = fit 0.5 + popularity 0.3 (Bayesian, last 4 weeks) + novelty 0.2 (avoids the user’s last 30 picks). Works signed out (no personal history). Read-only.",
        "security": [{}, { "ogqUserSession": [] }],
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": ["cardnews", "thumbnail", "tiktok", "banner", "ppt"]
            }
          },
          { "name": "preset", "in": "query", "required": true, "schema": { "type": "string" } },
          {
            "name": "pages",
            "in": "query",
            "required": false,
            "schema": { "type": "integer", "minimum": 1, "maximum": 10 }
          },
          {
            "name": "withTitlePage",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["0", "1"] },
            "description": "0 = first page is a content page."
          },
          {
            "name": "tone",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["cute", "serious", "humor", "emotional", "info"]
            }
          },
          { "name": "lang", "in": "query", "required": false, "schema": { "type": "string" } },
          {
            "name": "shape",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Dot-joined text shape words: list, short, question, numbers, long."
          },
          {
            "name": "contentId",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "maxLength": 200 },
            "description": "Prefer templates less used for this content."
          }
        ],
        "responses": {
          "200": {
            "description": "Suggestions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "templates": {
                      "type": "array",
                      "maxItems": 3,
                      "items": {
                        "type": "object",
                        "properties": {
                          "template_id": { "type": "string" },
                          "key": { "type": "string" },
                          "name": {
                            "type": "string",
                            "description": "Name in the requested language (falls back to English, then key)."
                          },
                          "score": { "type": "number" },
                          "preview": {
                            "type": "object",
                            "properties": {
                              "families": { "type": "array", "items": { "type": "string" } },
                              "hierarchy": {
                                "type": "string",
                                "enum": ["title-xl/body-s", "title-l/sub-m/body-s", "quote", "list"]
                              },
                              "density": {
                                "type": "string",
                                "enum": ["sparse", "medium", "dense"]
                              },
                              "numbering": { "type": "string", "enum": ["none", "chips", "cards"] },
                              "label": { "type": "boolean" },
                              "bubbles": { "type": "integer", "minimum": 0, "maximum": 2 },
                              "closingBand": { "type": "boolean" },
                              "placement": { "type": "string" }
                            }
                          }
                        }
                      }
                    },
                    "auto": {
                      "type": "boolean",
                      "description": "Auto (no template) is always available."
                    },
                    "status": { "type": "string" },
                    "verification": { "type": "object" },
                    "next_action": { "type": "string" },
                    "tool_confidence": { "type": "number" }
                  }
                }
              }
            }
          },
          "400": { "description": "Invalid format, preset or pages." },
          "404": { "description": "Rova is disabled." }
        }
      }
    },
    "/me/rova/jobs": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "My Rova jobs (newest first, 20 per page)",
        "operationId": "listMyRovaJobs",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Jobs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "next_cursor": {
                      "type": ["string", "null"]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — storage or content source unavailable (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/me/rova/character-card/{contentId}": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Creator studio — Rova character card (read)",
        "description": "Reads the signed-in creator's character card for one of their contents (name, personality, catchphrase, likes, taboos, supporting cast) and the Rova-only off switch. `all` reads the creator-wide switch. Owner only — someone else's content is 404.",
        "operationId": "getMyRovaCharacterCard",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "description": "Your content id, or `all` for the creator-wide Rova switch.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Character card (empty defaults when none was saved).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": ["ok", "saved"]
                    },
                    "content_id": {
                      "type": "string"
                    },
                    "card": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "maxLength": 30
                        },
                        "personality": {
                          "type": "array",
                          "maxItems": 3,
                          "items": {
                            "type": "string",
                            "maxLength": 12
                          }
                        },
                        "catchphrase": {
                          "type": "string",
                          "maxLength": 40
                        },
                        "likes": {
                          "type": "string",
                          "maxLength": 60
                        },
                        "taboos": {
                          "type": "array",
                          "maxItems": 10,
                          "items": {
                            "type": "string",
                            "maxLength": 20
                          }
                        },
                        "cast": {
                          "type": "array",
                          "maxItems": 3,
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "note": {
                                "type": "string"
                              }
                            },
                            "required": ["name"],
                            "additionalProperties": false
                          }
                        },
                        "rovaOff": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    },
                    "rova_off": {
                      "type": "boolean"
                    },
                    "updated_at": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED · ROVA_CONTENT_NOT_FOUND (not your content).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID — bad contentId.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Creator studio — Rova character card (save)",
        "description": "Saves the character card (one row per content, upsert — repeating the same body is idempotent) and appends one audit log row. `all` saves only the creator-wide Rova-only off switch. Card text is used inside Rova image requests; URLs are rejected and quote/bracket characters are removed. No money, mail or external calls.",
        "operationId": "putMyRovaCharacterCard",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "description": "Your content id, or `all` for the creator-wide Rova switch.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 30
                  },
                  "personality": {
                    "type": "array",
                    "maxItems": 3,
                    "items": {
                      "type": "string",
                      "maxLength": 12
                    }
                  },
                  "catchphrase": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "likes": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "taboos": {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "type": "string",
                      "maxLength": 20
                    }
                  },
                  "cast": {
                    "type": "array",
                    "maxItems": 3,
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "note": {
                          "type": "string"
                        }
                      },
                      "required": ["name"],
                      "additionalProperties": false
                    }
                  },
                  "rovaOff": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Character card (empty defaults when none was saved).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": ["ok", "saved"]
                    },
                    "content_id": {
                      "type": "string"
                    },
                    "card": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "maxLength": 30
                        },
                        "personality": {
                          "type": "array",
                          "maxItems": 3,
                          "items": {
                            "type": "string",
                            "maxLength": 12
                          }
                        },
                        "catchphrase": {
                          "type": "string",
                          "maxLength": 40
                        },
                        "likes": {
                          "type": "string",
                          "maxLength": 60
                        },
                        "taboos": {
                          "type": "array",
                          "maxItems": 10,
                          "items": {
                            "type": "string",
                            "maxLength": 20
                          }
                        },
                        "cast": {
                          "type": "array",
                          "maxItems": 3,
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "note": {
                                "type": "string"
                              }
                            },
                            "required": ["name"],
                            "additionalProperties": false
                          }
                        },
                        "rovaOff": {
                          "type": "boolean"
                        }
                      },
                      "additionalProperties": false
                    },
                    "rova_off": {
                      "type": "boolean"
                    },
                    "updated_at": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED · ROVA_CONTENT_NOT_FOUND (not your content).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID — bad contentId · ROVA_CARD_INVALID — card fields failed validation (see `fields`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/me/rova/earnings": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Creator studio — Rova earnings this month (KST)",
        "description": "Counts Rova jobs that fans made with the signed-in creator's content this month: jobs, accrued share in KRW (only jobs whose creator share has been settled to the settlement ledger), jobs still waiting for settlement, jobs with no share (free trial / granted credits), top 3 contents and per-format counts. Read-only — the money source of truth is the settlement ledger.",
        "operationId": "getMyRovaEarnings",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "Earnings summary.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "month": {
                      "type": "string"
                    },
                    "jobs": {
                      "type": "integer"
                    },
                    "accrued_krw": {
                      "type": "integer"
                    },
                    "pending_jobs": {
                      "type": "integer"
                    },
                    "zero_jobs": {
                      "type": "integer"
                    },
                    "reversed_jobs": {
                      "type": "integer"
                    },
                    "top_contents": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "formats": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_EARNINGS_UNAVAILABLE — storage unavailable (retry later).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/me/rova/consent/{key}": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Creator studio — Rova consent (read)",
        "description": "Owner only. Whether you have opened AI derivative creation (Rova) for this content or IP, the current terms version (draft — before legal review), and the demand: people waiting now, the last 7 days and today. Rova stays locked for users until you agree (no deemed consent).",
        "operationId": "getMyRovaConsent",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "Your content id, or `ip:{ipAssetId}` for one of your IP assets (applies to every content in that IP).",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Consent state and demand.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": ["ok", "saved"]
                    },
                    "key": {
                      "type": "string"
                    },
                    "consented": {
                      "type": "boolean"
                    },
                    "consented_at": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "consented_terms_version": {
                      "type": ["string", "null"]
                    },
                    "terms_version": {
                      "type": "string"
                    },
                    "terms_draft": {
                      "type": "boolean"
                    },
                    "demand": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        },
                        "last7": {
                          "type": "array",
                          "items": {
                            "type": "integer"
                          },
                          "minItems": 7,
                          "maxItems": 7
                        },
                        "today": {
                          "type": "integer"
                        }
                      }
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID — bad key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "ROVA_CONSENT_NOT_OWNER — not your content or IP.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED · ROVA_CONTENT_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Creator studio — Rova consent (agree · withdraw)",
        "description": "Owner only. `consent` needs `agree: true` (the checkbox) and the current `terms_version`; one append-only row is recorded (who · when · terms version · where). Sending the same state again writes nothing. Withdrawing is accepted only from Settings and blocks new creations only — running jobs and existing results stay. On consent, people who pressed «notify me» get one email each after the response (only when the server mail switch is on; otherwise only the send list is recorded). No money.",
        "operationId": "postMyRovaConsent",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "Your content id, or `ip:{ipAssetId}` for one of your IP assets (applies to every content in that IP).",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            },
            "description": "Same key + same body replays the first response (Idempotent-Replayed: true); same key + different body is 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": ["consent", "revoke"]
                  },
                  "agree": {
                    "type": "boolean",
                    "enum": [true]
                  },
                  "terms_version": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "settings",
                      "notification",
                      "content",
                      "studio_upload",
                      "studio_ip",
                      "detail"
                    ],
                    "description": "Where the creator acted. Consent is accepted from any of these; withdrawal (`revoke`) only from `settings` (others are 403 `ROVA_CONSENT_REVOKE_SETTINGS_ONLY`). `detail` is the legacy name of `content`."
                  }
                },
                "required": ["action", "terms_version", "source"],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved (or unchanged — `status: ok`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": ["ok", "saved"]
                    },
                    "key": {
                      "type": "string"
                    },
                    "consented": {
                      "type": "boolean"
                    },
                    "consented_at": {
                      "type": ["string", "null"],
                      "format": "date-time"
                    },
                    "consented_terms_version": {
                      "type": ["string", "null"]
                    },
                    "terms_version": {
                      "type": "string"
                    },
                    "terms_draft": {
                      "type": "boolean"
                    },
                    "demand": {
                      "type": "object",
                      "properties": {
                        "count": {
                          "type": "integer"
                        },
                        "last7": {
                          "type": "array",
                          "items": {
                            "type": "integer"
                          },
                          "minItems": 7,
                          "maxItems": 7
                        },
                        "today": {
                          "type": "integer"
                        }
                      }
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID · ROVA_CONSENT_AGREE_REQUIRED (tick the checkbox) · IDEMPOTENCY_KEY_REQUIRED · IDEMPOTENCY_KEY_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "ROVA_CONSENT_NOT_OWNER — not your content or IP · ROVA_CONSENT_REVOKE_SETTINGS_ONLY — withdrawal is accepted only from Settings (`source: settings`; `next_action: open_settings`, `settings_href`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED · ROVA_CONTENT_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ROVA_CONSENT_TERMS_STALE — the screen showed an old terms version (reload) · IDEMPOTENCY_KEY_REUSED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rova/content/{contentId}/demand": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Rova — «notify me when it opens» count",
        "description": "Public. How many people want this character opened (current «want» state, one per person · cached ~15 s — screens re-read every `refresh_seconds`), whether it is open, and (signed in) your own state. Contents in an IP share the IP key. Who pressed is never returned.",
        "operationId": "getRovaDemand",
        "tags": ["Rova"],
        "security": [],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "ip",
            "in": "query",
            "required": false,
            "description": "The content's IP asset id (counts are kept per IP when the content belongs to one).",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Demand count.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": ["ok", "saved"]
                    },
                    "key": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer",
                      "description": "People whose current state is «want» (each person counted once)."
                    },
                    "consented": {
                      "type": "boolean"
                    },
                    "me": {
                      "type": ["string", "null"],
                      "enum": ["want", "none", null]
                    },
                    "refresh_seconds": {
                      "type": "integer"
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID — bad id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE — retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Rova — press or cancel «notify me when it opens»",
        "description": "Signed-in users only. Allowed only while the creator has not agreed yet (the only thing blocking Rova). The creator cannot press it on their own content. One current state per person and key — pressing again writes nothing. No money, mail or external calls.",
        "operationId": "postRovaDemand",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "parameters": [
          {
            "name": "contentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{8,128}$"
            },
            "description": "Same key + same body replays the first response (Idempotent-Replayed: true); same key + different body is 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": ["want", "cancel"]
                  }
                },
                "required": ["action"],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved (or unchanged).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": ["ok", "saved"]
                    },
                    "key": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer",
                      "description": "People whose current state is «want» (each person counted once)."
                    },
                    "consented": {
                      "type": "boolean"
                    },
                    "me": {
                      "type": ["string", "null"],
                      "enum": ["want", "none", null]
                    },
                    "refresh_seconds": {
                      "type": "integer"
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "ROVA_INPUT_INVALID · IDEMPOTENCY_KEY_REQUIRED · IDEMPOTENCY_KEY_INVALID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "ROVA_DEMAND_OWNER (your own content) · ROVA_NOT_ALLOWED (the creator did not allow derivative works).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED · ROVA_CONTENT_NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "ROVA_ALREADY_OPEN — already open, create instead · IDEMPOTENCY_KEY_REUSED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "ROVA_STORE_UNAVAILABLE · ROVA_CONTENT_UNAVAILABLE — retry later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/me/rova/demand": {
      "servers": [
        {
          "url": "https://stg.nova.ogq.me/api",
          "description": "Staging (current)"
        }
      ],
      "get": {
        "summary": "Creator studio — demand for my IPs",
        "description": "Creator only. People who pressed «notify me» on your contents and IPs (per key, most first) and the total. Who pressed is never returned.",
        "operationId": "getMyRovaDemand",
        "tags": ["Rova"],
        "security": [
          {
            "ogqUserSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "My demand.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "task_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "title": {
                            "type": ["string", "null"]
                          },
                          "content_id": {
                            "type": "string"
                          },
                          "count": {
                            "type": "integer"
                          },
                          "consented": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "verification": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "next_action": {
                      "type": "string"
                    },
                    "tool_confidence": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "LOGIN_REQUIRED — sign in first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "ROVA_DISABLED.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}
