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

# List silos

> Lists the silos at the plants your key can access.
Pass `plant_id` to restrict the results to one plant.

Filter by `external_id` to resolve one of your codes to a single silo.
Paginated — see [Pagination](/pagination).




## OpenAPI

````yaml GET /v2/silos
openapi: 3.1.0
info:
  title: Emidat API
  version: '2.0'
  description: >
    The Emidat API v2 lets manufacturers create products and supplier products

    programmatically — designed for ERP and system integrations.


    Authentication uses a simple API key (`X-API-Key` header). Keys are issued

    per manufacturer and managed in the Emidat dashboard.


    Keys follow the format `emidat-{key_id}-{secret}`, where `key_id` is a

    random public handle.


    **Onboarding steps** — performed once before creating products:

    - Plant and production process setup (via Emidat UI)

    - Your material codes → Emidat material types and plant codes → Emidat
    plants are mapped in your integration middleware during setup; at runtime
    you send your own codes and the middleware resolves them

    - Create supplier companies via `POST /v2/supplier-companies` — every
    supplier plant needs one, as `supplier_company_id` is required

    - Create supplier plants via `POST /v2/supplier-plants`, referencing a
    supplier company by its Emidat `id`

    - Create supplier products using your own `external_id`; reference them in a
    product's BOM by their Emidat `id` (from the create response, or resolved
    via `GET …?external_id=`)

    - (Optional) Create silos to merge same-type supplier products from
    different suppliers — reference by their Emidat `id` in a product's BOM


    **Preview endpoints** — the `Product Instances` and `Prechain Products` tags

    are in preview. They are live and supported, but their contract is not
    frozen:

    request and response shapes, field names, and error codes may still change
    in

    ways that break existing integrations, possibly without a deprecation
    period.
servers:
  - url: https://api.emidat.com
    description: Production
security:
  - ApiKeyAuth: []
paths:
  /v2/silos:
    get:
      tags:
        - Silos
      summary: List silos
      description: |
        Lists the silos at the plants your key can access.
        Pass `plant_id` to restrict the results to one plant.

        Filter by `external_id` to resolve one of your codes to a single silo.
        Paginated — see [Pagination](/pagination).
      operationId: v2_silos_list
      parameters:
        - name: plant_id
          in: query
          required: false
          schema:
            type: string
            format: uuid
          description: >
            Optional Emidat plant UUID to restrict the results. A UUID you
            cannot

            reach simply matches nothing — the page comes back empty.
        - name: external_id
          in: query
          required: false
          schema:
            type: string
          description: >
            Narrow the list to the silo carrying this code of yours. Optional;
            at

            most one silo matches.
        - $ref: '#/components/parameters/CursorParam'
        - $ref: '#/components/parameters/LimitParam'
      responses:
        '200':
          description: One page of silos.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SiloList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          description: Malformed `plant_id` or `cursor`, or `limit` out of range.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  parameters:
    CursorParam:
      name: cursor
      in: query
      required: false
      schema:
        type: string
      description: >
        Opaque cursor taken from the previous page's `next_cursor`. Omit it for
        the

        first page. Never construct or parse one — its encoding is not part of
        the

        contract. A cursor that cannot be decoded is rejected with `422`. See

        [Pagination](/pagination).
    LimitParam:
      name: limit
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 200
        default: 50
      description: >
        Maximum number of items on the page. Out of range is rejected with
        `422`.

        See [Pagination](/pagination).
  schemas:
    SiloList:
      type: object
      description: One page of silos.
      required:
        - data
        - next_cursor
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Silo'
        next_cursor:
          anyOf:
            - type: string
            - type: 'null'
          description: >
            Pass back as `cursor` to fetch the next page. `null` on the last
            page —

            the only reliable end-of-collection signal.
    Error:
      type: object
      required:
        - msg
        - err_code
      properties:
        msg:
          type: string
          description: Human-readable explanation, for logs and operators. Do not parse it.
          example: supplier product requires a supplier plant
        err_code:
          type: string
          description: >
            Stable, machine-readable error code — branch on this, never on
            `msg`.

            The set may grow over time; treat an unrecognized code as

            non-retryable and surface it to an operator. The enum lists every

            code the platform can emit; only a subset is reachable per

            endpoint — see [Errors](/errors) for the actionable catalog.


            `LcaRecomputeJob.err_code` reports failures from this same `err_*`

            namespace. `LcaBlocker.err_code` does not — those values are a

            separate, disjoint set.
          example: err_supplier_product_missing_supplier_plant
          enum:
            - err_not_defined
            - err_not_found
            - err_not_valid
            - err_not_authenticated
            - err_permission_denied
            - err_declaration_not_completed
            - err_declaration_not_regenerable
            - err_epd_document_already_exists
            - err_invalid_product_ids
            - err_generate_products_limit
            - err_plant_missing_product_category
            - err_plant_incomplete_address
            - err_plant_incomplete_company_fields
            - err_plant_categories_not_covering_processes
            - err_plant_categories_not_covering_active_products
            - err_plant_invalid_category_id
            - err_plant_custom_electricity_mix_not_allowed
            - err_plant_electricity_mix_mismatch
            - err_plant_negative_electricity_values
            - err_plant_electricity_without_mix
            - err_electricity_plant_production_mismatch
            - err_lca_mass_balance
            - err_lca_allocation_data_incomplete
            - err_lca_production_output_mismatch
            - err_product_mass_larger_than_recipe_mass
            - err_product_category_not_allowed_at_plant
            - err_water_not_scoped_but_wastewater_is_scoped
            - err_more_wastewater_than_water
            - err_project_no_products
            - err_invalid_product_quantity
            - err_duplicate_product
            - err_product_missing_gwp_total
            - err_elementary_deactivated
            - err_product_missing_supplier
            - err_epd_unusable
            - err_epd_service
            - err_lca_update_not_queued
            - err_not_ready_for_epd
            - err_material_not_hazardous
            - err_material_no_limited_lifetime
            - err_invalid_lifetime_years
            - err_invalid_secondary_percentage_range
            - err_secondary_percentage_not_customizable
            - err_moisture_content_not_bio_based
            - err_invalid_moisture_content_range
            - err_declaration_not_exists
            - err_declaration_not_under_review
            - err_no_manufacturer
            - err_wrong_email_domain
            - err_user_exists
            - err_inviter_email_not_found
            - err_composite_used_in_supplier_products
            - err_composite_name_exists
            - err_plant_io_invalid_field
            - err_plant_io_field_not_switchable
            - err_plant_io_value_not_scoped
            - err_field_is_plant_level
            - err_negative_io_value
            - err_plant_io_mixed_allocation_groups
            - err_inies_sworn_statement_exists
            - err_supplier_in_use
            - err_supplier_name_exists
            - err_supplier_plant_in_use
            - err_supplier_plant_name_exists
            - err_supplier_product_in_recipe
            - err_supplier_product_in_silo
            - err_supplier_product_missing_supplier_plant
            - err_silo_in_use
            - err_silo_name_exists
            - err_elementary_unknown_matching
            - err_product_document_not_deletable
            - err_product_has_declarations
            - err_product_instance_in_recipe
            - err_prechain_product_in_recipe
            - err_prechain_product_exists
            - err_ccf_exists
            - err_ccf_not_completed
            - err_external_id_exists
            - err_bulk_upload_invalid_file
            - err_material_type_not_found
            - err_material_type_not_configured
            - err_unit_not_allowed_for_material
            - err_production_process_not_found
            - err_multiple_production_processes
            - err_process_plant_mismatch
            - err_material_process_incompatible
            - err_composite_not_allowed_in_recipe
            - err_elementary_not_allowed_in_recipe
            - err_prechain_circular_reference
            - err_product_type_no_recipe
            - err_product_mass_not_set
            - err_required_cell_empty
            - err_plant_not_found
            - err_plant_no_access
            - err_multiple_plants
            - err_product_already_exists
            - err_multiple_products
            - err_linked_product_type_mismatch
            - err_tech_spec_not_recognized
            - err_recipe_incomplete
            - err_orphan_row
            - err_duplicate_tech_spec
            - err_empty_sheet
            - err_no_products
            - err_tech_spec_invalid_value
            - err_dtp_service
            - err_data_translation_wrong_step
            - err_data_translation_invalid_plant_mapping
            - err_data_translation_unresolved_reference
            - err_data_translation_incomplete
            - err_data_translation_material_not_available
            - err_recycled_content_proof_missing
            - err_ppwr_declaration_exists
            - err_ppwr_declaration_editable_exists
            - err_ppwr_declaration_frozen
            - err_ppwr_doc_number_unavailable
            - err_ppwr_variant_mass_invalid
            - err_ppwr_variant_dimension_invalid
            - err_ppwr_variant_material_repeated
            - err_ppwr_variant_material_type
            - err_ppwr_invalid_field_key
            - err_ppwr_supplier_request_not_packaging_manufacturer
            - err_ppwr_supplier_request_pending
            - err_ppwr_supplier_request_not_pending
            - err_ppwr_field_not_requested
            - err_ppwr_document_limit_reached
            - err_ppwr_generation_not_packaging_manufacturer
            - err_ppwr_declaration_incomplete
            - err_ppwr_invalid_signatory
            - err_ppwr_invitation_send_failed
            - err_ppwr_supplier_link_placeholder_missing
            - err_ppwr_supplier_subject_missing
            - err_ppwr_supplier_email_missing
            - err_ppwr_verification_code_limit
            - err_ppwr_verification_code_send_failed
            - err_ppwr_email_not_verified
            - err_ppwr_attestation_required
            - err_ppwr_document_not_deletable
            - err_proof_document_limit
            - err_proof_size_limit
            - err_transport_route_unavailable
            - err_transport_missing_coordinates
            - err_transport_no_route
            - err_transport_same_address
            - err_reauthentication_required
            - err_two_factor_required
    Silo:
      type: object
      required:
        - id
        - external_id
        - plant_id
        - name
        - items
        - created_at
      properties:
        id:
          type: string
          format: uuid
          description: Emidat-assigned silo UUID.
        external_id:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Your own code for this silo, `null` when none is set. BOM entries
            reference it by its Emidat `id`, not this code.
          example: CEMENT_SILO_MUNICH_1
        plant_id:
          type: string
          format: uuid
          description: The plant's Emidat UUID.
        name:
          type: string
          description: Human-readable silo name.
          example: Cement Silo 1 (Munich)
        items:
          type: array
          items:
            $ref: '#/components/schemas/SiloItem'
          description: >-
            Supplier products constituting this silo, with yearly purchase
            volumes.
        created_at:
          type: string
          format: date-time
    SiloItem:
      type: object
      required:
        - supplier_product_id
        - annual_items
      description: |
        One supplier product contributing to a silo, with the volumes purchased
        from that supplier per calendar year. All items in a silo share the
        same material type — the same elementary, or the same composite; the
        unit is derived from it.
      properties:
        supplier_product_id:
          type: string
          format: uuid
          description: The supplier product's Emidat UUID.
        annual_items:
          type: array
          minItems: 1
          description: Volumes purchased per calendar year, in the material's unit.
          items:
            type: object
            required:
              - year
              - amount
            properties:
              year:
                type: integer
                description: Calendar year.
                example: 2024
              amount:
                type: number
                description: Volume purchased in that year.
                example: 5000
  responses:
    Unauthorized:
      description: >
        No credentials; or the key is malformed, unknown, revoked, or expired.
        The

        response is uniform and does not reveal which check failed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >
        A valid key lacked the required permission, or targeted a resource
        outside

        its access.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalServerError:
      description: An unexpected server error occurred. Surface it to an operator.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: |
        Per-manufacturer API key in the `X-API-Key` header, format
        `emidat-{key_id}-{secret}` where `key_id` is a random public handle.
        Issued by an owner in the Emidat
        dashboard; carries its own permission scopes, optional plant
        restrictions, and optional expiry. A revoked, expired, or unknown key
        returns 401. See the Authentication guide for details.

````