> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plantpredict.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Import a PVFARM project onto an existing prediction

> Imports the shading model file PVFARM's **Export Shading model (.pvfshade)** button
produces, building the power plant and its 3D shade scene on an existing prediction.

Send the file exactly as PVFARM exported it. A `.pvfshade` file is the compressed
form of the same data; an uncompressed `.json` of that data is also accepted, though
PVFARM does not export one. The import runs asynchronously and can take a few
minutes, so this returns `202 Accepted` immediately with a job ID. Poll
`GET /Project/Import/PVFarm/{jobId}` with that ID until the status is `Completed`
or `Failed`.

The target prediction must be a Block Builder prediction with a weather file already
selected. A prediction that already has a built power plant is refused unless the
call carries `overwriteExistingPowerPlant=true` — the explicit consent to replace it,
and the API twin of the confirmation the web application collects. There is no silent
default.

Unlike the web application there is no review step: the import creates one Module per
module type and one Inverter per inverter type from the file's datasheet values, then
builds the plant and the scene. A file that cannot be imported faithfully — an
unrecognized module technology, a fixed-tilt project, an old format version — fails
with a caller-fixable error code. **Nothing is ever substituted automatically.**

See the [PVFARM import guide](/api-docs/pvfarm-import) for a full walkthrough.

**Parameters:**

- `projectId` (path, required): The project containing the target prediction.
- `predictionId` (path, required): The prediction to build the power plant on.
- `overwriteExistingPowerPlant` (query, optional): Set to `true` to replace an
  existing power plant and its 3D scene. Defaults to `false`, which refuses.




## OpenAPI

````yaml /api-docs/api-reference/plantpredict-api.yaml post /Project/{projectId}/Prediction/{predictionId}/Import/PVFarm
openapi: 3.1.0
info:
  title: PlantPredict API
  version: 12.13.0
  description: >
    ## What is PlantPredict?


    PlantPredict is an industry-leading performance modeling platform for
    utility-scale

    solar power plants. It predicts energy yield across the full project
    lifecycle —

    from early-stage site prospecting through detailed engineering and
    operational

    monitoring. The same engine that powers the PlantPredict web UI is fully
    exposed

    via this REST API, enabling automation of complex, high-time-resolution
    energy

    predictions without any UI interaction.


    ## Domain Model — read this first


    Understanding the object hierarchy is essential before calling the API:


    - **Weather** — A weather file (hourly irradiance, temperature, wind, etc.)
    for a
      geographic location. Imported from a provider (e.g. SolarAnywhere, Meteonorm) or
      uploaded manually. Weather files live in a company-wide library and are referenced
      by Predictions.

    - **Module** — A PV module definition parameterized with electrical
    characteristics
      (STC power, temperature coefficients, single-diode model parameters, IAM curves,
      etc.). Modules live in a company-wide library.

    - **Inverter** — An inverter definition with efficiency curves,
    voltage/power ratings,
      and optional kVA derating curves. Inverters live in a company-wide library.

    - **Project** — A named location (lat/lon) that acts as a container for one
    or more
      Predictions. Holds geographic metadata (country, elevation, UTC offset) and a status.

    - **Prediction** — The core simulation configuration nested under a Project.
    Defines
      the simulation period, model selections (transposition, air mass, degradation,
      soiling, shading, spectral shift models), uncertainty error terms, and references
      to a Weather file. A Prediction must be linked to a PowerPlant before it can be run.
      Status values: 0 = Draft, 1 = Active, 2 = Issued, 3 = Archived.

    - **PowerPlant** — The physical plant design attached to a Prediction.
    Describes the
      electrical topology: Blocks → Arrays → Inverters → DC Fields (strings of modules).
      Also includes transformers, transmission lines, energy storage (ESS), availability
      losses, and LGIA export limits.

    - **Shade Scene** — An optional 3D shading model (PVJ format) attached to a
      Prediction's DC Fields. Supports import from PVC or SHD files. Shade and TABT
      (Tracker Angle Back-Tracking) calculations are queued and run asynchronously.

    ## Typical workflow to run a prediction


    1. Ensure a **Weather** file exists (search, download, or import one).

    2. Ensure a **Module** and **Inverter** exist in the library.

    3. **POST /Project** — create a project at the site location.

    4. **POST /Project/{projectId}/Prediction** — create a prediction with model
    settings.

    5. **POST /Project/{projectId}/Prediction/{predictionId}/PowerPlant** —
    attach a plant
       design referencing your module and inverter.
    6. **POST /Project/{projectId}/Prediction/{predictionId}/Run** — queue the
    simulation.

    7. Poll **GET /Project/{projectId}/Prediction/{predictionId}/Overview**
    until
       `status` reaches 2 (complete), then retrieve results via `/ResultSummary`,
       `/ResultDetails`, or `/NodalJson`.

    ## Authentication


    OAuth 2.0 **Client Credentials** flow via AWS Cognito. The spec advertises

    a single `bearerAuth` scheme — fetch a token yourself with the snippet

    below, then either paste it into the in-browser playground or pass it on

    every request as `Authorization: Bearer <token>`.


    > **Why not advertise OAuth2 directly?** Most users have access to the

    > production tenant only, and we don't want to invite anyone to enter

    > long-lived `client_id` / `client_secret` credentials into a third-party

    > documentation site. Keep credentials in your own environment; ship

    > short-lived bearer tokens to wherever they are needed.


    - Token URL:
    `https://terabase-prd.auth.us-west-2.amazoncognito.com/oauth2/token`

    - Scopes: `transactions/get` (read), `transactions/post` (write) — request
      both to access the entire surface.
    - Send credentials as **Basic Auth** in the token request header.


    Example:


    ```bash

    curl -X POST
    'https://terabase-prd.auth.us-west-2.amazoncognito.com/oauth2/token' \
      -u "$PP_CLIENT_ID:$PP_CLIENT_SECRET" \
      -d 'grant_type=client_credentials&scope=transactions/get transactions/post'
    ```


    API credentials (Client ID + Secret) are generated per user by a company
    admin

    inside the PlantPredict UI (gear icon → user profile → Generate API
    Credentials).

    Store them securely — they are shown only once.


    ## Notes


    - All request/response bodies are JSON (`Content-Type: application/json`).

    - The API is stateless — every request must supply complete inputs; there is
    no session.

    - POST operations that create entities return `{"id": <integer>}`.

    - Many integer fields (model types, status codes) map to named enums — use
      `GET /Definitions` to retrieve the full enum catalog at runtime.
    - Long-running operations (Run, Shade calculations, TABT) are asynchronous;
    poll
      the corresponding `ProcessingStatus` endpoint to track progress.
    - Responses may include an `X-Message` header with non-blocking warnings
    (e.g.
      duplicate project name).
servers:
  - url: https://api.plantpredict.terabase.energy
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Definitions
    description: Enum and model type definitions
  - name: Projects
    description: Solar project management
  - name: Predictions
    description: Energy prediction configuration and execution
  - name: PowerPlant
    description: Power plant design (blocks, arrays, inverters, transformers)
  - name: TimeSeries
    description: Custom time series data inputs
  - name: Results
    description: Prediction results — summary, details, nodal, average energy
  - name: FinancialModel
    description: Financial model parameters and cashflow results
  - name: Reports
    description: Report generation and export
  - name: ShadeScene
    description: 3D shade scene management and calculations
  - name: Weather
    description: Weather file import, download, and management
  - name: Inverters
    description: Inverter library management
  - name: Modules
    description: PV module library and single-diode parameter generation
  - name: ASHRAE
    description: ASHRAE climate station lookup
  - name: System
    description: System version and maintenance status
  - name: Company
    description: Company settings and user management
  - name: Country
    description: Reference country data
paths:
  /Project/{projectId}/Prediction/{predictionId}/Import/PVFarm:
    post:
      tags:
        - Projects
      summary: Import a PVFARM project onto an existing prediction
      description: >
        Imports the shading model file PVFARM's **Export Shading model
        (.pvfshade)** button

        produces, building the power plant and its 3D shade scene on an existing
        prediction.


        Send the file exactly as PVFARM exported it. A `.pvfshade` file is the
        compressed

        form of the same data; an uncompressed `.json` of that data is also
        accepted, though

        PVFARM does not export one. The import runs asynchronously and can take
        a few

        minutes, so this returns `202 Accepted` immediately with a job ID. Poll

        `GET /Project/Import/PVFarm/{jobId}` with that ID until the status is
        `Completed`

        or `Failed`.


        The target prediction must be a Block Builder prediction with a weather
        file already

        selected. A prediction that already has a built power plant is refused
        unless the

        call carries `overwriteExistingPowerPlant=true` — the explicit consent
        to replace it,

        and the API twin of the confirmation the web application collects. There
        is no silent

        default.


        Unlike the web application there is no review step: the import creates
        one Module per

        module type and one Inverter per inverter type from the file's datasheet
        values, then

        builds the plant and the scene. A file that cannot be imported
        faithfully — an

        unrecognized module technology, a fixed-tilt project, an old format
        version — fails

        with a caller-fixable error code. **Nothing is ever substituted
        automatically.**


        See the [PVFARM import guide](/api-docs/pvfarm-import) for a full
        walkthrough.


        **Parameters:**


        - `projectId` (path, required): The project containing the target
        prediction.

        - `predictionId` (path, required): The prediction to build the power
        plant on.

        - `overwriteExistingPowerPlant` (query, optional): Set to `true` to
        replace an
          existing power plant and its 3D scene. Defaults to `false`, which refuses.
      operationId: importPVFarmProject
      parameters:
        - name: projectId
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - name: predictionId
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - name: overwriteExistingPowerPlant
          in: query
          required: false
          schema:
            type: boolean
            default: false
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    The `.pvfshade` file exactly as PVFARM exported it. An
                    uncompressed `.json` of the same data is also accepted.
              required:
                - file
      responses:
        '202':
          description: >
            The import was accepted and is now running. Nothing has been built
            on the

            prediction yet.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PVFarmImportStartResult'
              example:
                jobId: 316
                statusUrl: /Project/Import/PVFarm/316
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    PVFarmImportStartResult:
      type: object
      description: >
        Returned when a PVFARM import is accepted. Nothing is built on the
        prediction yet —

        poll `statusUrl` until the job reaches a terminal status.
      properties:
        jobId:
          type: integer
          format: int64
          description: >
            Identifier for this import. Worth logging: it is the fastest way for
            support to

            find a specific import.
        statusUrl:
          type: string
          description: Relative URL to poll for the import status.
      required:
        - jobId
    ModelStateError:
      type: object
      description: |
        ASP.NET Web API validation error. `modelState` maps the offending
        field name (or `request`) to a list of human-readable messages.
      properties:
        message:
          type: string
        modelState:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
      required:
        - message
  responses:
    BadRequest:
      description: |
        The request was rejected. PlantPredict returns one of two shapes:

        * `application/json` with `{message, modelState}` for input
          validation errors (ASP.NET Web API model-state). The `modelState`
          map keys field names to lists of human-readable error messages.
        * `text/plain` with a free-form message for runtime / database
          errors that bubble up before validation completes.

        Clients should branch on the `Content-Type` header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ModelStateError'
          example:
            message: The request is invalid.
            modelState:
              latitude:
                - The field Latitude must be between -90 and 90.
        text/plain:
          schema:
            type: string
          example: A successfully completed prediction cannot be cancelled.
    Unauthorized:
      description: >-
        Missing or invalid bearer token. The response body is empty and no
        `Content-Type` header is set; the 401 status code is the only signal.
        Fetch a fresh token (see the **Authentication** section of the API
        description) and retry.
    NotFound:
      description: >-
        The referenced resource does not exist or is not accessible to the
        caller.
      content:
        text/plain:
          schema:
            type: string
          example: Project not found.
    ServerError:
      description: |
        Unexpected server-side error. The body is usually a plain-text message
        but its structure is not guaranteed — treat it as opaque diagnostic
        text. Common causes: database constraint violation, downstream
        service timeout, internal exception. Retry-safe for idempotent
        requests; for non-idempotent ones, verify state before retrying.
      content:
        text/plain:
          schema:
            type: string
          example: An error has occurred.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Pass `Authorization: Bearer <token>` on every request. See the
        **Authentication** section of the API description for how to fetch a
        token.

````