{
  "openapi": "3.0.1",
  "info": {
    "title": "Digipan API",
    "description": "Digipan REST API — Image services, authentication, and generic data fetch.",
    "version": "v1"
  },
  "paths": {
    "/api/AdminFetch": {
      "post": {
        "tags": [
          "AdminFetch"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/amp/getcerts": {
      "get": {
        "tags": [
          "Amp"
        ],
        "summary": "Returns one bounded page of the AMP certificates query as a single JSON document.\r\nThe wire format is column-major: a top-level `columns` array lists every column name\r\nonce, and `rows` is a 2D array of values in that column order. Pagination metadata\r\n(`pageNumber`, `pageSize`, `totalRecords`, `totalPages`, `hasMore`,\r\n`rowCount`) tells the caller whether to fetch the next page.\r\n            \r\npageSize defaults to 5000 and is capped at 5000 so a caller cannot\r\nrequest the whole (~90k row) set in one response; pageNumber defaults\r\nto 1. Paging is done with `ORDER BY ... OFFSET/FETCH`.\r\n            \r\nCorporateID is taken from the authenticated session — never from the query string. Optional\r\nfilters myAssetIds (comma-separated) and parcelId\r\nnarrow the result set. Authorization scope is corporate-wide by design: the underlying\r\nquery filters only on `CorporateID` (matching the source procedure body, which has no\r\nuser-level predicate). The session's UserID is intentionally not used as a row filter.\r\n            \r\nformat selects the row shape: the default (and any unrecognized value)\r\nkeeps the compact column-major arrays; `format=objects` returns each row as a JSON\r\nobject keyed by column name. The `columns` array and all pagination metadata are\r\npresent in both modes.",
        "parameters": [
          {
            "name": "myAssetIds",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "parcelId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "pageNumber",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 5000
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Auth/token": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Auth/refresh": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/ClerkTest/claims": {
      "get": {
        "tags": [
          "ClerkTest"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Data/call": {
      "post": {
        "tags": [
          "Data"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "Digipan_API"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "tags": [
          "Digipan_API"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/EducationCenter/UploadFile": {
      "post": {
        "tags": [
          "EducationCenter"
        ],
        "summary": "Upload an Education Center content file to S3 with a public-read ACL.\r\nAccepts multipart/form-data with a single `file` field and a\r\n`ContentType` form field of Article, Webinar, or Video (case-insensitive,\r\ntrailing slash tolerated) that selects the S3 folder. Only images,\r\nbrowser-playable videos (mp4, webm), PDFs, and document files are\r\naccepted. Maximum size: 50 MB for ALL file types (videos included);\r\nlarger videos must use the presigned direct-to-S3 flow via\r\n`GetUploadUrl`.\r\nThe file is streamed to S3 without in-memory buffering.",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "contentType": {
                    "type": "string"
                  }
                }
              },
              "encoding": {
                "file": {
                  "style": "form"
                },
                "contentType": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/EducationCenter/GetUploadUrl": {
      "post": {
        "tags": [
          "EducationCenter"
        ],
        "summary": "Issue a time-limited presigned S3 PUT URL so the browser can upload large\r\nEducation Center files (videos up to 500 MB) directly to S3, bypassing the\r\nAPI server. Applies the same validation as `UploadFile`: ContentType\r\nfolder mapping, extension allow-list, and per-type size limits (500 MB for\r\nvideos, 50 MB otherwise) based on the client-declared file size.\r\nThe client must PUT the file to `UploadUrl` with the returned\r\n`MimeType` as the Content-Type header and `x-amz-acl: public-read`.\r\nThe URL expires after 20 minutes.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/GetUploadUrlRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetUploadUrlRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/GetUploadUrlRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/GetUploadUrlRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/ExtraFeatures/GetRssFeeds": {
      "get": {
        "tags": [
          "Extra Features"
        ],
        "summary": "Search Google News and return the matching articles as JSON.",
        "description": "Wraps the Google News RSS search feed\r\n(`https://news.google.com/rss/search`). The upstream call has a 10 second\r\ntimeout; slow or failing upstream responses surface as `502 Bad Gateway`.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "description": "Search terms. Required.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RssFeedResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RssFeedResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RssFeedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "502": {
            "description": "Bad Gateway",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/File/download": {
      "get": {
        "tags": [
          "File"
        ],
        "summary": "Stream an arbitrary object from S3 to the caller as a file attachment.",
        "description": "Bucket resolution order: explicit bucket query param →\r\n`AWS:DownloadBucketName` setting → `AWS:BucketName` setting.\r\n            \r\nDesigned for arbitrarily large payloads (200 MB+). The action:\r\n  - sets `Content-Length` from S3's `GetObject` metadata so the client\r\n    can render a real progress bar (and avoids chunked transfer encoding),\r\n  - disables ASP.NET Core response buffering for this request,\r\n  - opts out of HTTPS response compression (compressing already-compressed\r\n    binaries wastes CPU and would re-buffer the stream),\r\n  - disables Kestrel's `MinResponseDataRate` for this request only so\r\n    legitimately slow clients on a multi-hundred-MB download are not killed,\r\n  - copies the S3 network stream straight into `Response.Body` via\r\n    `CopyToAsync` with the standard 81 920-byte buffer — no `byte[]`\r\n    materialization, so server memory stays flat regardless of object size.\r\n            \r\nRange / partial-content / resumable downloads are out of scope — only a single\r\n`Accept-Ranges: bytes` hint is advertised.",
        "parameters": [
          {
            "name": "document",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/File/upload": {
      "post": {
        "tags": [
          "File"
        ],
        "summary": "Upload a file to S3. Accepts multipart/form-data with a single file field.\r\nThe 'bucket' query parameter is required.\r\nMaximum file size: 5 MB. Supported formats: jpg, jpeg, png, gif, bmp, pdf,\r\ndoc, docx, xls, xlsx, csv, txt, zip.",
        "parameters": [
          {
            "name": "bucket",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              },
              "encoding": {
                "file": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/File": {
      "delete": {
        "tags": [
          "File"
        ],
        "summary": "Delete an object from S3 by key and bucket.\r\nReturns 204 No Content on success, 404 if the key does not exist.\r\nThe key must be scoped to the caller's corporate prefix (Corp_{corporateId}/).",
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "bucket",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/GenericFetch": {
      "post": {
        "tags": [
          "GenericFetch"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/GenericFetch/serverless": {
      "post": {
        "tags": [
          "GenericFetch"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Image/streetview": {
      "post": {
        "tags": [
          "Image"
        ],
        "summary": "Get a Google Street View image for the given location.",
        "description": "Falls back to a satellite image when Street View imagery is unavailable.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Image/satellite": {
      "post": {
        "tags": [
          "Image"
        ],
        "summary": "Get a Google Static Maps satellite image for the given location.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Image/both": {
      "post": {
        "tags": [
          "Image"
        ],
        "summary": "Get both Street View and satellite images in parallel; returns base64-encoded JSON.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Image/geofence": {
      "post": {
        "tags": [
          "Image"
        ],
        "summary": "Render a satellite image with the supplied polygon(s) and/or marker(s) overlaid.",
        "description": "Polygons can be supplied either as explicit lists of points or as a SQL Server\r\nWKT string (POLYGON / MULTIPOLYGON). At least one polygon (with 3+ points) or\r\none marker is required. The geofence cache key is a SHA-256 hash of the\r\ncanonicalized polygon/marker payload — polygon and marker LIST order does not\r\naffect the key (in-polygon point order does, since it defines the shape).",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/GeofenceRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GeofenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/GeofenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/GeofenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/images/local/streetview": {
      "post": {
        "tags": [
          "ImageByDb"
        ],
        "summary": "Get a Google Street View image; location resolved from the database.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/images/local/satellite": {
      "post": {
        "tags": [
          "ImageByDb"
        ],
        "summary": "Get a Google Static Maps satellite image; location resolved from the database.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/images/local/both": {
      "post": {
        "tags": [
          "ImageByDb"
        ],
        "summary": "Get both Street View and satellite images in parallel; location resolved from the database. Returns base64 JSON.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/images/local/geofence": {
      "post": {
        "tags": [
          "ImageByDb"
        ],
        "summary": "Render a satellite image with the property's polygon overlaid; polygon WKT resolved from the database.",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalGeofenceRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalGeofenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LocalGeofenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LocalGeofenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/PublicFetch": {
      "post": {
        "tags": [
          "PublicFetch"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SfRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/stripe/webhook/{corporateId}": {
      "post": {
        "tags": [
          "Stripe"
        ],
        "summary": "Receives and verifies Stripe webhook events for a specific corporate tenant.\r\nThe corporateId in the URL identifies which tenant's webhook secret to use for verification.",
        "parameters": [
          {
            "name": "corporateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/SwitchCorporate": {
      "post": {
        "tags": [
          "SwitchCorporate"
        ],
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/SwitchCorporateRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SwitchCorporateRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SwitchCorporateRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SwitchCorporateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/Test/primary-market": {
      "get": {
        "tags": [
          "Test"
        ],
        "summary": "Streams sp_TestPrimaryMarket as NDJSON. The wire format is column-major:\r\nthe `count` event lists every column name once in a top-level `columns`\r\narray (including dynamic columns from #tempAdvTable), and each `batch`\r\nevent ships `rows` as a 2D array of values in that column order.\r\n            \r\nEach NDJSON event is true-incrementally flushed: this action disables response\r\nbuffering via M:Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature.DisableBuffering and opts\r\nout of the response-compression middleware via\r\nMicrosoft.AspNetCore.Http.Features.IHttpsCompressionFeature, then writes through\r\n`Response.BodyWriter` (a System.IO.Pipelines.PipeWriter) so each\r\nper-event flush drains bytes through Kestrel to the client socket immediately —\r\nthe first `batch` reaches the client well before the SP has finished\r\nstreaming the rest of the result set.\r\n            \r\nThe `parallelWaves` query parameter is accepted for backwards compatibility\r\nand is ignored — the endpoint now invokes the SP exactly once with PageSize set\r\nto the requested value (or int.MaxValue when 0/negative).",
        "parameters": [
          {
            "name": "auctionId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 84912
            }
          },
          {
            "name": "corporateId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 69
            }
          },
          {
            "name": "userId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 7922
            }
          },
          {
            "name": "userRoleId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "showProspects",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "parallelWaves",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 3
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiError": {
        "type": "object",
        "properties": {
          "errorID": {
            "type": "integer",
            "format": "int32"
          },
          "errorName": {
            "type": "string",
            "nullable": true
          },
          "errorMessage": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "GeofenceRequest": {
        "type": "object",
        "properties": {
          "parcelId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "reapiId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "wkt": {
            "type": "string",
            "nullable": true
          },
          "polygons": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/LatLng"
              }
            },
            "nullable": true
          },
          "markers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LatLng"
            },
            "nullable": true
          },
          "width": {
            "type": "integer",
            "format": "int32"
          },
          "height": {
            "type": "integer",
            "format": "int32"
          },
          "fillColor": {
            "type": "string",
            "nullable": true
          },
          "borderColor": {
            "type": "string",
            "nullable": true
          },
          "borderWeight": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "GetUploadUrlRequest": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "description": "Original file name, including extension.",
            "nullable": true
          },
          "fileSize": {
            "type": "integer",
            "description": "Declared file size in bytes (validated against per-type limits).",
            "format": "int64"
          },
          "contentType": {
            "type": "string",
            "description": "Article, Webinar, or Video (case-insensitive, trailing slash tolerated).",
            "nullable": true
          },
          "mimeType": {
            "type": "string",
            "description": "MIME type the browser will send in the PUT request (e.g. video/mp4).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Request body for M:Digipan_API.Controllers.EducationCenterController.GetUploadUrl(Digipan_API.Controllers.EducationCenterController.GetUploadUrlRequest)."
      },
      "ImageRequest": {
        "type": "object",
        "properties": {
          "parcelId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "reapiId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "latitude": {
            "type": "number",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "format": "double"
          },
          "width": {
            "type": "integer",
            "format": "int32"
          },
          "height": {
            "type": "integer",
            "format": "int32"
          },
          "heading": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "pitch": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "fov": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LatLng": {
        "type": "object",
        "properties": {
          "latitude": {
            "type": "number",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "LocalGeofenceRequest": {
        "type": "object",
        "properties": {
          "parcelId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "reapiId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "width": {
            "type": "integer",
            "format": "int32"
          },
          "height": {
            "type": "integer",
            "format": "int32"
          },
          "fillColor": {
            "type": "string",
            "nullable": true
          },
          "borderColor": {
            "type": "string",
            "nullable": true
          },
          "borderWeight": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "LocalImageRequest": {
        "type": "object",
        "properties": {
          "parcelId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "reapiId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "width": {
            "type": "integer",
            "format": "int32"
          },
          "height": {
            "type": "integer",
            "format": "int32"
          },
          "heading": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "pitch": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "fov": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RefreshRequest": {
        "type": "object",
        "properties": {
          "refreshToken": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RssFeedItem": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "nullable": true
          },
          "link": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RssFeedResponse": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "nullable": true
          },
          "fetchedAt": {
            "type": "string",
            "format": "date-time"
          },
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RssFeedItem"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SfRequest": {
        "type": "object",
        "properties": {
          "isCompressed": {
            "type": "boolean"
          },
          "ipAddress": {
            "type": "string",
            "nullable": true
          },
          "json": {
            "type": "object",
            "description": "Arbitrary JSON object",
            "nullable": true
          },
          "operationName": {
            "type": "string",
            "nullable": true
          },
          "apiVersion": {
            "$ref": "#/components/schemas/SpSchema"
          },
          "prefix": {
            "$ref": "#/components/schemas/SpPrefix"
          }
        },
        "additionalProperties": false
      },
      "SpPrefix": {
        "enum": [
          "esf",
          "sf",
          "rsf",
          "asf",
          "psf"
        ],
        "type": "string"
      },
      "SpSchema": {
        "enum": [
          "api",
          "api_v2",
          "dbo"
        ],
        "type": "string"
      },
      "SwitchCorporateRequest": {
        "type": "object",
        "properties": {
          "corporateID": {
            "type": "integer",
            "format": "int32"
          },
          "marketplaceCorpIDs": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "activeSubdomain": {
            "type": "string",
            "nullable": true
          },
          "host": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TokenRequest": {
        "type": "object",
        "properties": {
          "subdomain": {
            "type": "string",
            "nullable": true
          },
          "host": {
            "type": "string",
            "nullable": true
          },
          "marketplaceCorpIDs": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "impersonateUserID": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "Enter your JWT token",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "security": [
    {
      "Bearer": [ ]
    }
  ]
}