Direct Marketing Tariff Upload API - Complete User Guide

Overview

This guide explains how to upload Direct Marketing tariff offers to the system using JSON files. You can upload single or multiple offers with different configurations for capacity ranges, pricing models, and time periods.

Endpoint: POST /tariff-management/direct-marketing/upload File Type: JSON uploaded as multipart/form-data

Note: For information on how versioning, price updates, and the contract-options API work, see the Price Upload Guide.


Table of Contents

  1. Quick Start
  2. What is a Direct Marketing Offer
  3. JSON Structure Overview
  4. Field Reference
  5. Complete JSON Examples - All Combinations
  6. How to Upload
  7. Response Format
  8. Validation Rules
  9. Common Mistakes
  10. Troubleshooting

Quick Start

  1. Create a JSON file with your Direct Marketing offer data
  2. Validate the JSON structure matches one of the examples below
  3. Upload using the API endpoint with Bearer authentication
  4. Check response for success or error messages

What is a Direct Marketing Offer

A Direct Marketing offer defines pricing and terms for selling energy through direct marketing contracts:


JSON Structure Overview

Single Offer Upload

{
  "offer": {
    "name": "Offer Name",
    "tariffType": 3,
    "countryCode": "DE",
    "configuration": { ... },
    "fees": { ... },
    "priceMatrix": [ ... ],
    "otherPriceComponents": { ... }
  }
}

Batch Upload (Multiple Offers)

{
  "offers": [
    { "name": "First Offer", ... },
    { "name": "Second Offer", ... }
  ]
}

Note: Use either offer (singular) or offers (plural), not both.


Field Reference

Root Level

Field Type Required Description
offer object Yes* Single offer (for uploading one offer)
offers array Yes* Array of offers (for batch upload)

*Use one or the other, not both.


Offer Object

Field Type Required Description Example
name string Yes Descriptive name for the offer "Solar EEG Spot 2026"
tariffType integer Yes Must be 3 for Direct Marketing 3
countryCode string Yes ISO 3166-1 alpha-2 country code "DE", "AT"
description string No Optional detailed description "EEG solar spot pricing"
configuration object Yes Technical configuration See below
fees object Yes Default fee structure See below
priceMatrix array Yes Array of pricing contracts See below
otherPriceComponents object Yes Additional price components See below

Configuration Object

Field Type Required Allowed Values Description
technology string Yes "Solar", "Wind" Energy source type
directMarketingType string Yes "EEG", "Other" Marketing contract type
enumerationType string Yes "Spot", "MarketValue" Price calculation basis
serviceFeeType string Yes "Relative", "Absolute" Fee calculation method
capacityTiers array No Array of capacity ranges Creates separate offers per tier

Capacity Tiers

capacityTiers is an array of capacity range objects. Each tier creates a separate offer in the database.

Capacity Range Object:

Field Type Required Description
min decimal No Minimum capacity in kW (defaults to 0 if omitted)
max decimal No Maximum capacity in kW (use null for unlimited)

Examples:

Important Behavior:

Offer Uniqueness Requirements

Each offer must have a unique configuration in the system. You cannot upload two offers with identical configuration settings (same combination of technology, directMarketingType, enumerationType, serviceFeeType, and capacityTiers).

If you need to provide different pricing schedules, group them as multiple contracts within the priceMatrix array of a single offer rather than creating separate offers with the same configuration. This approach:

Example: Instead of creating two separate "Solar EEG Spot" offers with different start dates, create one offer with multiple contracts in the priceMatrix array, each with its own start period and pricing schedule.


Fees Object

Default fees that apply to all pricing periods unless overridden:

Field Type Required Description
guaranteeOfOriginFeeEurPerMWh decimal No Default Guarantee of Origin fee (EUR/MWh)
basicFeePerYear decimal No Default annual basic fee (EUR)

Price Matrix (Array of Contracts)

The priceMatrix is an array where each element represents a contract with a start period, duration (tenor), and pricing schedule.

Important: You can mix different time resolutions within the same priceMatrix. For example, you can have:

This allows you to provide multiple contract options with different pricing granularities.

Contract Object:

Field Type Required Description
start string Yes Start period: "YYYY" (yearly) or "YYYYMNN" (monthly)
tenor string No Contract duration: "3Y", "12M", etc. (auto-calculated if omitted)
prices object Yes Pricing schedule with period keys

Start Period Formats:

Note: Direct Marketing supports yearly and monthly resolutions. Quarterly pricing is not supported (use PPA contracts for quarterly pricing).

Tenor Formats:

Prices Object:

Keys are period identifiers (matching the start format). Each period contains pricing fields:

Field Type Required Description
fixedFeeEurPerMWh decimal No Fixed fee per MWh (EUR)
marketValuePercent decimal No Market value percentage (for Spot enumeration)
variableFixedFeeEurPerMWh decimal No Variable fixed fee per MWh (EUR)
guaranteeOfOriginFeeEurPerMWh decimal No Override default GOO fee for this period
basicFeePerYear decimal No Override default basic fee for this period

Note: At least one pricing field must be provided per period.


Other Price Components Object

Field Type Required Allowed Values Description
basicFeePerYear string Yes "None", "Location factor" Additional fee component type

Complete JSON Examples - All Combinations

1. Solar + Spot + Relative + Multiple Capacity Tiers

Most common scenario: Creates 3 separate offers with capacity-based pricing.

{
  "offer": {
    "name": "Solar EEG Spot 2026",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Solar spot market pricing with capacity tiers",
    "configuration": {
      "technology": "Solar",
      "directMarketingType": "EEG",
      "enumerationType": "Spot",
      "serviceFeeType": "Relative",
      "capacityTiers": [
        { "min": 0, "max": 99 },
        { "min": 100, "max": 249 },
        { "min": 250, "max": null }
      ]
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0.5,
      "basicFeePerYear": 180
    },
    "priceMatrix": [
      {
        "start": "2026",
        "tenor": "3Y",
        "prices": {
          "2026": {
            "fixedFeeEurPerMWh": 0,
            "marketValuePercent": 1.99,
            "variableFixedFeeEurPerMWh": 1.67
          },
          "2027": {
            "fixedFeeEurPerMWh": 0,
            "marketValuePercent": 2.05,
            "variableFixedFeeEurPerMWh": 1.70
          },
          "2028": {
            "fixedFeeEurPerMWh": 0,
            "marketValuePercent": 2.10,
            "variableFixedFeeEurPerMWh": 1.75
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "None"
    }
  }
}

Result: Creates 3 database offers:

Each offer has the same 3-year pricing schedule.


2. Wind + MarketValue + Absolute + No Capacity Tiers

Single offer without capacity restrictions: Creates 1 offer with absolute pricing.

{
  "offer": {
    "name": "Wind Market Value 2026",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Wind market value with absolute service fees",
    "configuration": {
      "technology": "Wind",
      "directMarketingType": "EEG",
      "enumerationType": "MarketValue",
      "serviceFeeType": "Absolute"
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0.3,
      "basicFeePerYear": 200
    },
    "priceMatrix": [
      {
        "start": "2026",
        "tenor": "2Y",
        "prices": {
          "2026": {
            "fixedFeeEurPerMWh": 2.50
          },
          "2027": {
            "fixedFeeEurPerMWh": 2.45
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "Location factor"
    }
  }
}

Result: Creates 1 offer with no capacity restrictions.


3. Solar + Spot + Relative + Monthly Pricing (12 months)

Monthly granularity: 12-month contract with monthly price variations.

{
  "offer": {
    "name": "Solar Spot Monthly 2026",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Monthly pricing for solar spot market",
    "configuration": {
      "technology": "Solar",
      "directMarketingType": "EEG",
      "enumerationType": "Spot",
      "serviceFeeType": "Relative",
      "capacityTiers": [
        { "min": 100, "max": 500 }
      ]
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0,
      "basicFeePerYear": 180
    },
    "priceMatrix": [
      {
        "start": "2026M03",
        "tenor": "12M",
        "prices": {
          "2026M03": {
            "marketValuePercent": 1.95,
            "variableFixedFeeEurPerMWh": 1.60
          },
          "2026M04": {
            "marketValuePercent": 1.93,
            "variableFixedFeeEurPerMWh": 1.58
          },
          "2026M05": {
            "marketValuePercent": 1.90,
            "variableFixedFeeEurPerMWh": 1.55
          },
          "2026M06": {
            "marketValuePercent": 1.88,
            "variableFixedFeeEurPerMWh": 1.52
          },
          "2026M07": {
            "marketValuePercent": 1.85,
            "variableFixedFeeEurPerMWh": 1.50
          },
          "2026M08": {
            "marketValuePercent": 1.87,
            "variableFixedFeeEurPerMWh": 1.52
          },
          "2026M09": {
            "marketValuePercent": 1.90,
            "variableFixedFeeEurPerMWh": 1.55
          },
          "2026M10": {
            "marketValuePercent": 1.92,
            "variableFixedFeeEurPerMWh": 1.57
          },
          "2026M11": {
            "marketValuePercent": 1.94,
            "variableFixedFeeEurPerMWh": 1.59
          },
          "2026M12": {
            "marketValuePercent": 1.96,
            "variableFixedFeeEurPerMWh": 1.61
          },
          "2027M01": {
            "marketValuePercent": 1.98,
            "variableFixedFeeEurPerMWh": 1.63
          },
          "2027M02": {
            "marketValuePercent": 2.00,
            "variableFixedFeeEurPerMWh": 1.65
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "None"
    }
  }
}

Result: Creates 1 offer with monthly pricing from March 2026 to February 2027.


4. Solar + Spot + Relative + Multiple Contracts (Different Start Years)

Multiple pricing contracts: Different contracts starting at different times.

{
  "offer": {
    "name": "Solar Multi-Contract",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Multiple contracts with different start dates",
    "configuration": {
      "technology": "Solar",
      "directMarketingType": "EEG",
      "enumerationType": "Spot",
      "serviceFeeType": "Relative",
      "capacityTiers": [
        { "min": 0, "max": 249 },
        { "min": 250, "max": null }
      ]
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0.5,
      "basicFeePerYear": 180
    },
    "priceMatrix": [
      {
        "start": "2026",
        "tenor": "2Y",
        "prices": {
          "2026": {
            "marketValuePercent": 1.99,
            "variableFixedFeeEurPerMWh": 1.67
          },
          "2027": {
            "marketValuePercent": 2.05,
            "variableFixedFeeEurPerMWh": 1.70
          }
        }
      },
      {
        "start": "2027",
        "tenor": "2Y",
        "prices": {
          "2027": {
            "marketValuePercent": 2.10,
            "variableFixedFeeEurPerMWh": 1.75
          },
          "2028": {
            "marketValuePercent": 2.15,
            "variableFixedFeeEurPerMWh": 1.80
          }
        }
      },
      {
        "start": "2028",
        "tenor": "1Y",
        "prices": {
          "2028": {
            "marketValuePercent": 2.20,
            "variableFixedFeeEurPerMWh": 1.85
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "None"
    }
  }
}

Result: Creates 2 offers (due to 2 capacity tiers), each with 3 contract options (2026, 2027, 2028 starts).


5. Wind + MarketValue + Absolute + Fee Overrides

Per-period fee overrides: Different fees for different years.

{
  "offer": {
    "name": "Wind with Fee Overrides",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Wind with year-specific fee adjustments",
    "configuration": {
      "technology": "Wind",
      "directMarketingType": "EEG",
      "enumerationType": "MarketValue",
      "serviceFeeType": "Absolute"
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0.5,
      "basicFeePerYear": 200
    },
    "priceMatrix": [
      {
        "start": "2026",
        "tenor": "3Y",
        "prices": {
          "2026": {
            "fixedFeeEurPerMWh": 2.50,
            "guaranteeOfOriginFeeEurPerMWh": 0.3,
            "basicFeePerYear": 150
          },
          "2027": {
            "fixedFeeEurPerMWh": 2.45,
            "guaranteeOfOriginFeeEurPerMWh": 0.3,
            "basicFeePerYear": 150
          },
          "2028": {
            "fixedFeeEurPerMWh": 2.40,
            "guaranteeOfOriginFeeEurPerMWh": 0.3,
            "basicFeePerYear": 150
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "Location factor"
    }
  }
}

Result: Creates 1 offer. Each year uses overridden fees instead of defaults.


6. Solar + MarketValue + Absolute + Single Capacity Tier

One capacity tier: Creates a single offer with capacity restriction.

{
  "offer": {
    "name": "Solar Market Value Large",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Large-scale solar installations only",
    "configuration": {
      "technology": "Solar",
      "directMarketingType": "Other",
      "enumerationType": "MarketValue",
      "serviceFeeType": "Absolute",
      "capacityTiers": [
        { "min": 1000, "max": null }
      ]
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0.2,
      "basicFeePerYear": 300
    },
    "priceMatrix": [
      {
        "start": "2026",
        "tenor": "3Y",
        "prices": {
          "2026": {
            "fixedFeeEurPerMWh": 1.80
          },
          "2027": {
            "fixedFeeEurPerMWh": 1.75
          },
          "2028": {
            "fixedFeeEurPerMWh": 1.70
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "None"
    }
  }
}

Result: Creates 1 offer named "Solar Market Value Large (>1000kW)".


7. Wind + Spot + Relative + Auto-Calculated Tenor

No tenor specified: System calculates tenor from the number of price periods.

{
  "offer": {
    "name": "Wind Spot Auto-Tenor",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Contract with automatically calculated tenor",
    "configuration": {
      "technology": "Wind",
      "directMarketingType": "EEG",
      "enumerationType": "Spot",
      "serviceFeeType": "Relative"
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0.4,
      "basicFeePerYear": 220
    },
    "priceMatrix": [
      {
        "start": "2026",
        "prices": {
          "2026": {
            "marketValuePercent": 2.00,
            "variableFixedFeeEurPerMWh": 1.50
          },
          "2027": {
            "marketValuePercent": 2.05,
            "variableFixedFeeEurPerMWh": 1.55
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "None"
    }
  }
}

Result: Creates 1 offer. Tenor is calculated as "2Y" (2 price periods).


8. Batch Upload - Multiple Offers at Once

Upload multiple offers in one request:

{
  "offers": [
    {
      "name": "Solar Spot Small",
      "tariffType": 3,
      "countryCode": "DE",
      "description": "Small solar installations",
      "configuration": {
        "technology": "Solar",
        "directMarketingType": "EEG",
        "enumerationType": "Spot",
        "serviceFeeType": "Relative",
        "capacityTiers": [
          { "min": 0, "max": 100 }
        ]
      },
      "fees": {
        "guaranteeOfOriginFeeEurPerMWh": 0.5,
        "basicFeePerYear": 150
      },
      "priceMatrix": [
        {
          "start": "2026",
          "tenor": "1Y",
          "prices": {
            "2026": {
              "marketValuePercent": 2.50,
              "variableFixedFeeEurPerMWh": 2.00
            }
          }
        }
      ],
      "otherPriceComponents": {
        "basicFeePerYear": "None"
      }
    },
    {
      "name": "Wind Market Value Large",
      "tariffType": 3,
      "countryCode": "DE",
      "description": "Large wind installations",
      "configuration": {
        "technology": "Wind",
        "directMarketingType": "EEG",
        "enumerationType": "MarketValue",
        "serviceFeeType": "Absolute",
        "capacityTiers": [
          { "min": 1000, "max": null }
        ]
      },
      "fees": {
        "guaranteeOfOriginFeeEurPerMWh": 0.3,
        "basicFeePerYear": 300
      },
      "priceMatrix": [
        {
          "start": "2026",
          "tenor": "3Y",
          "prices": {
            "2026": {
              "fixedFeeEurPerMWh": 2.00
            },
            "2027": {
              "fixedFeeEurPerMWh": 1.95
            },
            "2028": {
              "fixedFeeEurPerMWh": 1.90
            }
          }
        }
      ],
      "otherPriceComponents": {
        "basicFeePerYear": "Location factor"
      }
    }
  ]
}

Result: Creates 2 separate offers. Both are validated and imported in one request.


9. Solar + Spot + Relative + Mixed Time Resolutions (Yearly + Monthly)

Different time resolutions in the same priceMatrix: This example demonstrates that you can mix yearly and monthly contracts within the same offer. Each contract in the priceMatrix array can have its own time resolution.

{
  "offer": {
    "name": "Solar Mixed Pricing",
    "tariffType": 3,
    "countryCode": "DE",
    "description": "Offers both yearly and monthly contract options",
    "configuration": {
      "technology": "Solar",
      "directMarketingType": "EEG",
      "enumerationType": "Spot",
      "serviceFeeType": "Relative",
      "capacityTiers": [
        { "min": 100, "max": 500 }
      ]
    },
    "fees": {
      "guaranteeOfOriginFeeEurPerMWh": 0.5,
      "basicFeePerYear": 180
    },
    "priceMatrix": [
      {
        "start": "2026",
        "tenor": "3Y",
        "prices": {
          "2026": {
            "marketValuePercent": 1.99,
            "variableFixedFeeEurPerMWh": 1.67
          },
          "2027": {
            "marketValuePercent": 2.05,
            "variableFixedFeeEurPerMWh": 1.70
          },
          "2028": {
            "marketValuePercent": 2.10,
            "variableFixedFeeEurPerMWh": 1.75
          }
        }
      },
      {
        "start": "2026M06",
        "tenor": "6M",
        "prices": {
          "2026M06": {
            "marketValuePercent": 1.85,
            "variableFixedFeeEurPerMWh": 1.50
          },
          "2026M07": {
            "marketValuePercent": 1.83,
            "variableFixedFeeEurPerMWh": 1.48
          },
          "2026M08": {
            "marketValuePercent": 1.85,
            "variableFixedFeeEurPerMWh": 1.50
          },
          "2026M09": {
            "marketValuePercent": 1.88,
            "variableFixedFeeEurPerMWh": 1.52
          },
          "2026M10": {
            "marketValuePercent": 1.90,
            "variableFixedFeeEurPerMWh": 1.55
          },
          "2026M11": {
            "marketValuePercent": 1.92,
            "variableFixedFeeEurPerMWh": 1.57
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "None"
    }
  }
}

Result: Creates 1 offer with two contract options at different time resolutions:

This demonstrates that the same priceMatrix can contain contracts with different time granularities.


10. Wind + Spot + Absolute + Minimal Fields

Minimum required fields only:

{
  "offer": {
    "name": "Wind Spot Minimal",
    "tariffType": 3,
    "countryCode": "DE",
    "configuration": {
      "technology": "Wind",
      "directMarketingType": "Other",
      "enumerationType": "Spot",
      "serviceFeeType": "Absolute"
    },
    "fees": {},
    "priceMatrix": [
      {
        "start": "2026",
        "prices": {
          "2026": {
            "fixedFeeEurPerMWh": 2.00
          }
        }
      }
    ],
    "otherPriceComponents": {
      "basicFeePerYear": "None"
    }
  }
}

Result: Creates 1 offer with minimal configuration. No default fees, single year pricing.


How to Upload

Using cURL (Command Line)

curl -X POST "https://your-api-domain.com/tariff-management/direct-marketing/upload" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: multipart/form-data" \
  -F "file=@your-offer.json"

Using PowerShell

$filePath = 'C:\path\to\your-offer.json'
$uri = 'https://your-api-domain.com/tariff-management/direct-marketing/upload'
$headers = @{ Authorization = 'Bearer YOUR_TOKEN' }
$form = @{ file = Get-Item $filePath }

Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Form $form

Using Postman

  1. Method: POST
  2. URL: https://your-api-domain.com/tariff-management/direct-marketing/upload
  3. Headers:
    • Authorization: Bearer YOUR_TOKEN
  4. Body:
    • Select form-data
    • Key: file (change type to File)
    • Value: Select your JSON file
  5. Send

Using JavaScript (Fetch API)

const formData = new FormData();
formData.append('file', fileInput.files[0]);

fetch('https://your-api-domain.com/tariff-management/direct-marketing/upload', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  body: formData
})
.then(response => response.json())
.then(data => console.log('Success:', data))
.catch(error => console.error('Error:', error));

Response Format

Success Response

When using capacityTiers, multiple results are returned - one per tier:

{
  "success": true,
  "results": [
    {
      "offerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "success": true,
      "message": "Imported successfully"
    },
    {
      "offerId": "7bc12d89-8a23-4c71-9def-5e432a1b8c92",
      "success": true,
      "message": "Imported successfully"
    },
    {
      "offerId": "9de45c01-2f34-4a87-8bcd-4d567e8f9a01",
      "success": true,
      "message": "Imported successfully"
    }
  ]
}

Without Capacity Tiers

Single result when no tiers are specified:

{
  "success": true,
  "results": [
    {
      "offerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "success": true,
      "message": "Imported successfully"
    }
  ]
}

Batch Upload Response

Multiple results for batch uploads:

{
  "success": true,
  "results": [
    {
      "offerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "success": true,
      "message": "Imported successfully"
    },
    {
      "offerId": "7bc12d89-8a23-4c71-9def-5e432a1b8c92",
      "success": true,
      "message": "Imported successfully"
    }
  ]
}

Error Response

If validation fails:

{
  "success": false,
  "results": [
    {
      "offerId": null,
      "success": false,
      "message": "Validation failed: TariffType must be 3 for Direct Marketing"
    }
  ]
}

Validation Rules

Required Fields

offer or offers must be present ✓ name, tariffType, countryCode required for each offer ✓ configuration with all 4 fields: technology, directMarketingType, enumerationType, serviceFeeTypefees object (can be empty {}) ✓ priceMatrix with at least one contract ✓ Each contract must have start and pricesotherPriceComponents with basicFeePerYear field

Field Validation

tariffType must be 3countryCode must be valid ISO 3166-1 alpha-2 (2 letters) ✓ Enum values must match exactly (case-sensitive): "Solar", "Wind", "EEG", "Other", "Spot", "MarketValue", "Relative", "Absolute" ✓ Period keys in prices must match start format (yearly: "YYYY", monthly: "YYYYMNN")

Capacity Tiers

✓ If provided, min must be less than max (when both are non-null) ✓ min and max must be non-negative ✓ Tiers can be omitted entirely (creates single offer without capacity restrictions)

Pricing

✓ At least one pricing field per period entry ✓ Decimal values must be valid numbers

Contract Logic

tenor is optional (auto-calculated from price periods if omitted) ✓ Multiple contracts can have overlapping or different time ranges


Common Mistakes

Wrong tariffType

"tariffType": 1  // WRONG - 1 is not Direct Marketing

Fix:

"tariffType": 3  // Correct for Direct Marketing

Using numeric enums instead of strings

"technology": 0,              // WRONG - Deprecated format
"directMarketingType": 1,     // WRONG - Deprecated format
"enumerationType": 0,         // WRONG - Deprecated format
"serviceFeeType": 0           // WRONG - Deprecated format

Fix:

"technology": "Solar",
"directMarketingType": "EEG",
"enumerationType": "Spot",
"serviceFeeType": "Relative"

Using capacityRange in priceMatrix

"priceMatrix": [
  {
    "start": "2026",
    "capacityRange": { "min": 0, "max": 100 },  // WRONG - Deprecated format
    "prices": { ... }
  }
]

Fix:

"configuration": {
  ...
  "capacityTiers": [
    { "min": 0, "max": 100 }  // Correct format
  ]
},
"priceMatrix": [
  {
    "start": "2026",
    "prices": { ... }  // No capacityRange here
  }
]

Missing required pricing field

"prices": {
  "2026": {}  // WRONG - No pricing fields
}

Fix:

"prices": {
  "2026": {
    "fixedFeeEurPerMWh": 2.00  // At least one field required
  }
}

Mismatched period keys

{
  "start": "2026",      // Yearly format
  "prices": {
    "2026M01": { ... }  // WRONG - Monthly format doesn't match
  }
}

Fix:

{
  "start": "2026",
  "prices": {
    "2026": { ... },    // Match yearly format
    "2027": { ... }
  }
}

Using both offer and offers

{
  "offer": { ... },   // WRONG - Can't use both
  "offers": [ ... ]
}

Fix (choose one):

// For single offer:
{
  "offer": { ... }
}

// For batch:
{
  "offers": [ ... ]
}

Invalid month format

"start": "2026M3"  // WRONG - Month must be 2 digits

Fix:

"start": "2026M03"  // Correct

Can I mix yearly and monthly contracts in the same offer?

Yes! You can have multiple contracts with different time resolutions in the same priceMatrix:

"priceMatrix": [
  {
    "start": "2026",
    "tenor": "2Y",
    "prices": {
      "2026": { ... },  // Yearly
      "2027": { ... }   // Yearly
    }
  },
  {
    "start": "2026M06",
    "tenor": "6M",
    "prices": {
      "2026M06": { ... },  // Monthly
      "2026M07": { ... },  // Monthly
      "2026M08": { ... }   // Monthly
    }
  }
]

This creates one offer with two contract options at different time granularities.


Troubleshooting

Issue: "TariffType must be 3"

Cause: You used a different tariff type number. Fix: Set "tariffType": 3


Issue: "Invalid enumeration value"

Cause: Used numeric values (0, 1) instead of strings, or misspelled enum. Fix: Use exact strings: "Solar", "Wind", "EEG", "Other", "Spot", "MarketValue", "Relative", "Absolute"


Issue: "Capacity range validation failed"

Cause: Deprecated format used (capacityRange inside priceMatrix contract). Fix: Move capacity ranges to configuration.capacityTiers (correct format).


Issue: "No pricing fields provided"

Cause: Empty prices object for a period. Fix: Add at least one pricing field: fixedFeeEurPerMWh, marketValuePercent, variableFixedFeeEurPerMWh, etc.


Issue: "Invalid JSON format"

Cause: Syntax error in JSON (missing comma, bracket, etc.). Fix: Validate JSON at jsonlint.com or use a JSON validator.


Issue: Multiple offers created unexpectedly

Cause: You provided capacityTiers in correct format. Explanation: This is expected behavior. Each tier creates a separate offer. Fix (if unwanted): Remove capacityTiers to create single offer without capacity restrictions.


Issue: "Tenor calculation failed"

Cause: Provided invalid or inconsistent price periods. Fix: Ensure price period keys are sequential and match the start format. Or explicitly provide tenor.


Summary Checklist

Before uploading:


Last Updated: December 2025 Endpoint: /tariff-management/direct-marketing/upload