{
  "openapi": "3.1.1",
  "info": {
    "title": "Godny-Zaufania.pl — API portfolio firm",
    "version": "1.1.0",
    "description": "Klucz Bearer przypisany do zweryfikowanego konta i jednej firmy. Panel: /firma/{nip}/api. Każdy zapis wymaga Idempotency-Key (24 h); zmiana istniejącej realizacji wymaga If-Match. Treść szkicu ma te same pola co kreator portalu. API nie aktywuje firm ani nie wysyła poczty. Dokumentacja: https://godny-zaufania.pl/api/docs."
  },
  "servers": [
    {
      "url": "https://godny-zaufania.pl"
    }
  ],
  "paths": {
    "/api/v1/companies/{nip}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Nip"
        }
      ],
      "get": {
        "operationId": "getCompany",
        "summary": "Zweryfikowana firma, branże i limity",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/companies/{nip}/portfolio": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Nip"
        }
      ],
      "get": {
        "operationId": "listEntries",
        "summary": "Lista realizacji firmy",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9999,
              "default": 1
            }
          },
          {
            "name": "external_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$",
              "description": "Stały identyfikator źródłowy w obrębie firmy. Ponowne utworzenie zwraca istniejący wpis bez nadpisania, także po upływie 24 godzin."
            },
            "description": "Dokładne wyszukanie identyfikatora źródłowego (0 lub 1 wpis). Nie ujawnia wpisów innej firmy."
          }
        ],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createEntry",
        "summary": "Utwórz prywatny szkic",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "201": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                },
                "description": "Adres reprezentacji realizacji."
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Istniejąca realizacja o tym samym external_id. Nie została nadpisana.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                },
                "description": "Adres reprezentacji realizacji."
              }
            }
          }
        },
        "description": "Wymaga zakresu portfolio:write. Idempotencja obejmuje także zdjęcia i publikację.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEntry"
              }
            }
          }
        }
      }
    },
    "/api/v1/companies/{nip}/portfolio/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Nip"
        },
        {
          "$ref": "#/components/parameters/EntryId"
        }
      ],
      "get": {
        "operationId": "getEntry",
        "summary": "Odczytaj realizację i ETag",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateEntry",
        "summary": "Zmień wybrane pola szkicu",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Wymaga zakresu portfolio:write. Idempotencja obejmuje także zdjęcia i publikację.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchEntry"
              }
            }
          }
        }
      }
    },
    "/api/v1/companies/{nip}/portfolio/{id}/photos": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Nip"
        },
        {
          "$ref": "#/components/parameters/EntryId"
        }
      ],
      "post": {
        "operationId": "uploadPhoto",
        "summary": "Dodaj jedno zdjęcie do szkicu",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "201": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                },
                "description": "Adres reprezentacji realizacji."
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Wymaga zakresu portfolio:write. Idempotencja obejmuje także zdjęcia i publikację.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/PhotoUpload"
              }
            }
          }
        }
      }
    },
    "/api/v1/companies/{nip}/portfolio/{id}/photos/{photo}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Nip"
        },
        {
          "$ref": "#/components/parameters/EntryId"
        },
        {
          "$ref": "#/components/parameters/PhotoId"
        }
      ],
      "get": {
        "operationId": "getPrivatePhoto",
        "summary": "Pobierz własne zdjęcie jako WebP",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Zdjęcie z portfolio tej firmy. Wymaga klucza API.",
            "content": {
              "image/webp": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updatePhoto",
        "summary": "Zmień podpis, etap albo kolejność zdjęcia",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Wymaga zakresu portfolio:write. Idempotencja obejmuje także zdjęcia i publikację.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhotoUpdate"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removePhoto",
        "summary": "Usuń zdjęcie i wycofaj publiczną realizację",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Wymaga zakresu portfolio:write. Idempotencja obejmuje także zdjęcia i publikację.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Empty"
              }
            }
          }
        }
      }
    },
    "/api/v1/companies/{nip}/portfolio/{id}/publish": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Nip"
        },
        {
          "$ref": "#/components/parameters/EntryId"
        }
      ],
      "post": {
        "operationId": "publishEntry",
        "summary": "Opublikuj kompletny szkic na wizytówce",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Wymaga zakresu portfolio:write. Idempotencja obejmuje także zdjęcia i publikację.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Publish"
              }
            }
          }
        }
      }
    },
    "/api/v1/companies/{nip}/portfolio/{id}/withdraw": {
      "parameters": [
        {
          "$ref": "#/components/parameters/Nip"
        },
        {
          "$ref": "#/components/parameters/EntryId"
        }
      ],
      "post": {
        "operationId": "withdrawEntry",
        "summary": "Wycofaj publiczny wpis, zachowując szkic",
        "security": [
          {
            "CompanyApiKey": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "responses": {
          "200": {
            "description": "Sukces",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntryResponse"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                },
                "description": "Wersja do następnego If-Match."
              },
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nieprawidłowe żądanie lub brak Idempotency-Key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Brak lub nieaktywny klucz API",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "description": "Brak uprawnień lub weryfikacji firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Zasób nie istnieje lub należy do innej firmy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Metoda niedozwolona",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt klucza ponowienia lub stanu publikacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "412": {
            "description": "Nieaktualny ETag",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Przekroczony rozmiar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "Nieobsługiwany Content-Type",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Błąd walidacji",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Brak If-Match",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Limit żądań lub zapisów",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          },
          "500": {
            "description": "Błąd serwera",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Wymaga zakresu portfolio:write. Idempotencja obejmuje także zdjęcia i publikację.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Empty"
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "CompanyApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "gz_api_<id>_<secret>",
        "description": "Klucz z panelu zweryfikowanej firmy; portfolio:read lub portfolio:write."
      }
    },
    "parameters": {
      "Nip": {
        "name": "nip",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^[0-9]{10}$"
        }
      },
      "EntryId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^[a-f0-9]{32}$"
        }
      },
      "PhotoId": {
        "name": "photo",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^[a-f0-9]{32}$"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Unikalny klucz operacji, zachowywany przez 24 h. Ponowienie musi mieć ten sam payload, metodę, ścieżkę i If-Match. Nie używaj ponownie do nowej operacji.",
        "schema": {
          "type": "string",
          "minLength": 16,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{15,127}$"
        }
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "required": true,
        "description": "ETag bieżącej realizacji, np. \"3\". Nie jest wymagany przy tworzeniu.",
        "schema": {
          "type": "string",
          "pattern": "^\"[1-9][0-9]*\"$"
        },
        "example": "\"3\""
      }
    },
    "schemas": {
      "Draft": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120
          },
          "branch": {
            "type": "string",
            "maxLength": 100
          },
          "problem": {
            "type": "string",
            "maxLength": 1200
          },
          "scope": {
            "type": "string",
            "maxLength": 1200
          },
          "work": {
            "type": "string",
            "maxLength": 2200
          },
          "result": {
            "type": "string",
            "maxLength": 1200
          },
          "duration": {
            "type": "string",
            "maxLength": 100
          },
          "date": {
            "type": "string",
            "maxLength": 10
          },
          "cost": {
            "type": "string",
            "maxLength": 180
          },
          "cover": {
            "type": "string",
            "maxLength": 32
          }
        }
      },
      "CreateEntry": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120
          },
          "branch": {
            "type": "string",
            "maxLength": 100
          },
          "problem": {
            "type": "string",
            "maxLength": 1200
          },
          "scope": {
            "type": "string",
            "maxLength": 1200
          },
          "work": {
            "type": "string",
            "maxLength": 2200
          },
          "result": {
            "type": "string",
            "maxLength": 1200
          },
          "duration": {
            "type": "string",
            "maxLength": 100
          },
          "date": {
            "type": "string",
            "maxLength": 10
          },
          "cost": {
            "type": "string",
            "maxLength": 180
          },
          "cover": {
            "type": "string",
            "maxLength": 32
          },
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$",
            "description": "Stały identyfikator źródłowy w obrębie firmy. Ponowne utworzenie zwraca istniejący wpis bez nadpisania, także po upływie 24 godzin."
          }
        },
        "required": [
          "title",
          "branch"
        ]
      },
      "PatchEntry": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Draft"
          }
        ],
        "minProperties": 1
      },
      "Photo": {
        "type": "object",
        "required": [
          "id",
          "stage",
          "caption",
          "width",
          "height",
          "bytes",
          "url",
          "public_url"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-f0-9]{32}$"
          },
          "stage": {
            "type": "string",
            "enum": [
              "before",
              "during",
              "after"
            ]
          },
          "caption": {
            "type": "string",
            "maxLength": 180
          },
          "width": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1600
          },
          "height": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1600
          },
          "bytes": {
            "type": "integer",
            "minimum": 1
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "public_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "source_sha256": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[a-f0-9]{64}$",
            "description": "SHA-256 pliku wejściowego przed konwersją serwerową. Pozwala uzgodnić upload po utracie odpowiedzi. Starsze pliki mogą zwracać null."
          }
        }
      },
      "Entry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "company_nip",
          "status",
          "version",
          "draft",
          "photos",
          "published_snapshot",
          "publication_blocked",
          "moderation_note",
          "public_url",
          "published_at",
          "created_at",
          "updated_at",
          "external_id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[a-f0-9]{32}$"
          },
          "company_nip": {
            "type": "string",
            "pattern": "^[0-9]{10}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "draft": {
            "$ref": "#/components/schemas/Draft"
          },
          "photos": {
            "type": "array",
            "maxItems": 12,
            "items": {
              "$ref": "#/components/schemas/Photo"
            }
          },
          "published_snapshot": {
            "type": [
              "object",
              "null"
            ],
            "description": "Snapshot publicznej wersji; może różnić się od aktualnego szkicu."
          },
          "publication_blocked": {
            "type": "boolean"
          },
          "moderation_note": {
            "type": "string"
          },
          "public_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$",
            "description": "Stały identyfikator źródłowy w obrębie firmy. Ponowne utworzenie zwraca istniejący wpis bez nadpisania, także po upływie 24 godzin."
          }
        }
      },
      "EntryResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "additionalProperties": false,
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Entry"
          }
        }
      },
      "ListResponse": {
        "type": "object",
        "required": [
          "data",
          "pagination"
        ],
        "additionalProperties": false,
        "properties": {
          "data": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/Entry"
            }
          },
          "pagination": {
            "type": "object",
            "required": [
              "page",
              "per_page",
              "total",
              "pages"
            ],
            "properties": {
              "page": {
                "type": "integer",
                "minimum": 1
              },
              "per_page": {
                "const": 20
              },
              "total": {
                "type": "integer",
                "minimum": 0
              },
              "pages": {
                "type": "integer",
                "minimum": 1
              }
            }
          }
        }
      },
      "CompanyResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "nip",
              "name",
              "verified",
              "branches",
              "scope",
              "key_expires_at",
              "limits"
            ],
            "properties": {
              "nip": {
                "type": "string",
                "pattern": "^[0-9]{10}$"
              },
              "name": {
                "type": "string"
              },
              "verified": {
                "const": true
              },
              "branches": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "scope": {
                "type": "string",
                "enum": [
                  "portfolio:read",
                  "portfolio:write"
                ]
              },
              "key_expires_at": {
                "type": "string",
                "format": "date-time"
              },
              "limits": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            }
          }
        }
      },
      "Publish": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "rights_confirmed",
          "privacy_confirmed"
        ],
        "properties": {
          "rights_confirmed": {
            "type": "boolean",
            "const": true
          },
          "privacy_confirmed": {
            "type": "boolean",
            "const": true
          }
        }
      },
      "PhotoUpload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "photo",
          "stage",
          "caption"
        ],
        "properties": {
          "photo": {
            "type": "string",
            "format": "binary",
            "description": "JPG/PNG/WebP do 2097152 bajtów, 20 MP, minimum 16 px w każdym wymiarze."
          },
          "stage": {
            "type": "string",
            "enum": [
              "before",
              "during",
              "after"
            ]
          },
          "caption": {
            "type": "string",
            "minLength": 8,
            "maxLength": 180
          }
        }
      },
      "PhotoUpdate": {
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "minProperties": 1,
            "properties": {
              "stage": {
                "type": "string",
                "enum": [
                  "before",
                  "during",
                  "after"
                ]
              },
              "caption": {
                "type": "string",
                "minLength": 8,
                "maxLength": 180
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "move"
            ],
            "properties": {
              "move": {
                "type": "string",
                "enum": [
                  "up",
                  "down"
                ]
              }
            }
          }
        ]
      },
      "Empty": {
        "type": "object",
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "request_id"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "fields"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "fields": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "request_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    }
  }
}
