Price Upload API Documentation
Overview
The TRACE Price Upload API allows you to upload different types of energy tariff offers to the system using JSON files. The API supports multiple tariff types, each with its own specific format and requirements.
The Tariff Management module uses a versioning system for both Direct Marketing and PPA offers. Each upload creates a new version of the offer. Old versions remain in the history and are never deleted, but the system always uses the most recent version when retrieving contract options.
Table of Contents
- Authentication
- How Price Upload Works
- Available Tariff Types
- Querying Contract Options
- Common Features
- Best Practices
- Troubleshooting
Authentication
All endpoints require authentication using a Bearer token:
Authorization: Bearer YOUR_TOKEN
M2M Authentication Guide
To access the API, you need to obtain an access token using Machine-to-Machine (M2M) authentication. You will be provided with the following credentials:
- Client ID - Your unique application identifier
- Client Secret - Your confidential application secret
- API Domain - The base URL for authentication
- Audience - The target API identifier
Request Token
Endpoint: POST https://{your-api-domain}/api/auth/m2m-login
Headers:
Content-Type: application/json
Request Body:
{
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"audience": "your-audience-url"
}
Note: All credential values (clientId, clientSecret, audience, and API domain) will be provided to you during onboarding.
Response
A successful authentication returns:
{
"access_token": "eyJhbGc...",
"token_type": "Bearer",
"expires_in": 86400
}
| Field | Description |
|---|---|
access_token |
The JWT token to use for API requests |
token_type |
Always "Bearer" |
expires_in |
Token validity in seconds (86400 = 24 hours) |
Using the Token
Include the access token in the Authorization header for all API requests:
Authorization: Bearer eyJhbGc...
Note: Tokens expire after the time specified in expires_in. Request a new token before the current one expires to maintain uninterrupted access.
How Price Upload Works
Versioning System
When you upload an offer with the same configuration (tariff type, technology, PPA structure, direct marketing type, etc.), the system:
- Creates a new version of that offer
- Keeps all previous versions in history (never deleted)
- Uses the latest version (by
CreatedAttimestamp) when querying for contract options
Uploading New Prices
Direct Marketing Example:
{
"offer": {
"name": "Solar EEG Spot Relative 0-1000kW",
"tariffType": 3,
"technology": "Solar",
"configuration": {
"directMarketingType": "EEG",
"enumerationType": "Spot",
"serviceFeeType": "Relative",
"capacityTiers": [{ "min": 0, "max": 1000 }]
},
"priceMatrix": [
{ "start": "2026M02", "tenor": "11M", "prices": { ... } }
]
}
}
PPA Example:
{
"offer": {
"name": "PPA Upstream Solar 100-500kW",
"tariffType": 5,
"technology": "Solar",
"configuration": {
"ppaStructure": "PayAsProduced",
"guaranteeOfOrigin": "Provider",
"negativePrices": "Excluded",
"hedgeSharePercent": 100,
"capacityTiers": [{ "min": 100, "max": 500 }]
},
"priceMatrix": [
{ "start": "2026Q1", "tenor": "1Y", "prices": { "2026": { "priceEurPerMWh": 85.0 } } }
]
}
}
Updating Prices
To update prices for an existing configuration, upload a new offer with the same configuration but an updated priceMatrix. The new version will be used for all future queries.
Clearing Prices
To effectively "delete" prices for a specific configuration, upload an offer with an empty priceMatrix:
{
"offer": {
"name": "Solar EEG Spot Relative 0-1000kW - No Prices",
"tariffType": 3,
"technology": "Solar",
"configuration": {
"directMarketingType": "EEG",
"enumerationType": "Spot",
"serviceFeeType": "Relative",
"capacityTiers": [{ "min": 0, "max": 1000 }]
},
"priceMatrix": []
}
}
Result:
- New version created with zero schedules
contract-optionsAPI will return this offer but with no available contracts- Old versions with prices remain in history
Available Tariff Types
Direct Marketing Tariffs
Upload direct marketing tariff offers with capacity tiers and flexible pricing structures.
Features:
- Multiple technology types (Solar, Wind)
- Capacity tier configuration
- EEG and Market Value pricing
- Spot and fixed fee structures
Endpoint: POST /tariff-management/direct-marketing/upload
View Direct Marketing Documentation →
PPA Tariffs (Upstream & Downstream)
Upload Power Purchase Agreement offers for buying or selling energy.
Features:
- Upstream (selling) and Downstream (buying) contracts
- Multiple technologies (Solar, Wind, Biomass)
- Quarterly or yearly pricing
- Guarantee of Origin handling
- Flexible payment structures
Endpoint: POST /tariff-management/ppa/upload
Querying Contract Options
How It Works
The contract-options API retrieves offers based on:
- Configuration match - tariffType, technology, directMarketingType/ppaStructure, etc.
- Capacity match -
installedCapacity >= MinCapacity AND installedCapacity <= MaxCapacity - Most recent version - Always uses the latest offer by
CreatedAttimestamp
Capacity Range Behavior
Important: The system does NOT fall back to older versions. Only the most recent offer is considered.
Example Scenario:
Day 1: Upload offer with capacity 0-1000 kW and price 100 EUR/MWh
Day 2: Upload offer with capacity 0-500 kW and price 101 EUR/MWh
| Query | Result |
|---|---|
installedCapacity: 400 |
Returns Day 2 offer (0-500 kW, price 101) |
installedCapacity: 600 |
No offer found - Day 2 only covers 0-500 kW, Day 1 is ignored |
Key Behaviors
| Aspect | Behavior |
|---|---|
| Versioning | Each upload creates a new version (by CreatedAt timestamp) |
| Old Versions | Remain in database but are not deleted and not used by default |
| Latest Version | Always used by contract-options API |
| Empty PriceMatrix | Allowed - creates offer with zero schedules (effectively "deletes" prices) |
| Capacity Filtering | Only checks latest version; does not fall back to older versions |
| validAsOf Parameter | Optional - retrieve offers valid as of a specific date (CreatedAt <= validAsOf) |
Query Parameters
includeExpired: false- Filter out past contracts (default)validAsOf: "2026-01-23T00:00:00Z"- Get offers valid as of specific dateinstalledCapacity: 400- Filter by installed capacity
Example Queries
Direct Marketing:
POST /tariff-management/offers/schedules/contract-options
{
"configuration": {
"tariffType": 3,
"technology": "Solar",
"directMarketingType": "EEG",
"installedCapacity": 400
}
}
PPA:
POST /tariff-management/offers/schedules/contract-options
{
"configuration": {
"tariffType": 5,
"technology": "Solar",
"ppaStructure": "PayAsProduced",
"guaranteeOfOrigin": "Provider",
"negativePrices": "Excluded",
"hedgeSharePercent": 100,
"installedCapacity": 250
}
}
Historical Query (using validAsOf):
POST /tariff-management/offers/schedules/contract-options
{
"configuration": {
"installedCapacity": 600
},
"validAsOf": "2026-01-22T23:59:59Z"
}
Common Features
File Format
- Content-Type:
multipart/form-data - File Format: JSON
- Encoding: UTF-8
Upload Format
Both Direct Marketing and PPA support single and batch uploads:
Single:
{
"offer": {
"name": "Single Offer",
...
}
}
Batch:
{
"offers": [
{ "name": "Offer 1", ... },
{ "name": "Offer 2", ... }
]
}
Response Format
All endpoints return a standardized response:
{
"success": true,
"results": [
{
"offerId": "guid",
"success": true,
"message": "Imported successfully"
}
]
}
Error Handling
- 200 OK - Successful upload
- 400 Bad Request - Invalid request or file format
- 401 Unauthorized - Missing or invalid authentication
- 500 Internal Server Error - Server error during processing
Best Practices
- Updating Prices: Upload a new offer with the same configuration but updated
priceMatrix - Removing Prices: Upload an offer with empty
priceMatrix: [] - Capacity Changes: Be aware that narrowing capacity ranges will make larger capacities unavailable
- Historical Data: Use
validAsOfparameter to retrieve offers from a specific date - Testing: Always verify your uploads using the
contract-optionsAPI
Troubleshooting
Issue: "No offers found" despite uploading prices
Solution: Check if the capacity range covers the requested installedCapacity. Remember that only the latest version is used.
Issue: Old prices still showing
Solution: This shouldn't happen - system always uses latest version. Check CreatedAt timestamps.
Issue: Want to restore old pricing
Solution: Re-upload the old offer JSON (will create a new version with old prices)
Issue: Need to delete an offer completely
Solution: Offers are never truly deleted. Upload an offer with empty priceMatrix to effectively clear prices, or filter at query time using validAsOf before the offer was created.
Getting Help
If you encounter issues:
- Check the specific tariff type documentation for detailed requirements
- Validate your JSON file format
- Review error messages in the API response
- Contact the TRACE development team for support
API Versions
The API automatically detects the tariff type based on the JSON structure. Make sure to follow the correct format for your tariff type as specified in the respective documentation pages.