{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Creating custom tariffs"},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"creating-custom-tariffs","__idx":0},"children":["Creating custom tariffs"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["ev.energy schedules charging around the user's electricity tariff, so the tariff needs to be right. Most users can pick their tariff from the public list at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs"]},". If a user's tariff is not in that list, you can create a custom tariff from its rates and assign it to the user."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This guide covers:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#when-to-create-a-custom-tariff"},"children":["When to create a custom tariff"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#who-can-see-a-custom-tariff"},"children":["Who can see a custom tariff"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#creating-a-tariff"},"children":["Creating a tariff"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#assigning-the-tariff-to-a-user"},"children":["Assigning the tariff to a user"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#repricing-a-tariff"},"children":["Repricing a tariff"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#deleting-a-tariff"},"children":["Deleting a tariff"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#validation-errors"},"children":["Validation errors"]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Build it visually"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/tools/tariff-builder"},"children":["tariff builder"]}," turns a tariff's prices and hours into the request body, and checks it against the rules in this guide before you send it."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"when-to-create-a-custom-tariff","__idx":1},"children":["When to create a custom tariff"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create a custom tariff when:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["the user's tariff is not in the public list, for example a local supplier or a business tariff;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["the user has negotiated rates that differ from the published ones;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["your own product already knows the user's rates, and you want ev.energy to use exactly those rates."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Search the public list first. Public tariffs are kept up to date by ev.energy, including price changes. A custom tariff is only updated when you update it."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A custom tariff has fixed rates that repeat every week, with optional rates for public holidays. Dynamic tariffs, whose prices change every day, cannot be created this way."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"requirements","__idx":2},"children":["Requirements"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To begin you will need:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A valid Authorization token (see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/auth"},"children":["this page"]}," for instructions)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tariff:write"]}," scope to create, update and delete tariffs, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tariff:read"]}," to read them and their generated prices back."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user:write"]}," scope if you want to assign the tariff to a user, either by sending ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," when you create it or afterwards. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"#assigning-the-tariff-to-a-user"},"children":["Assigning the tariff to a user"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["region:read"]}," scope if you want to look up region URLs with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /regions"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"who-can-see-a-custom-tariff","__idx":3},"children":["Who can see a custom tariff"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A custom tariff created with the Client Credentials grant belongs to the organisation linked to the application that created it, and is private to that organisation."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs"]}," lists your organisation's custom tariffs alongside the public tariffs. It never lists another organisation's custom tariffs."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Another organisation's custom tariff returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs/{tariff_id}"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs/{tariff_id}/prices"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["When another organisation reads a resource that links to your custom tariff, such as a user's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["default_location.tariff"]},", the link renders as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," and cannot be expanded."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Webhooks follow the same rule. A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["charging_sub_session"]}," webhook sent to your organisation links to your custom tariff, and the same webhook sent to another organisation has ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tariff: null"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The one exception is ev.energy's own apps: a user who has your custom tariff sees it in the ev.energy app. They cannot change or delete it."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Only your organisation can update or delete the tariff."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Only the Client Credentials grant creates and manages tariffs for your organisation, and only when your application is linked to one: otherwise ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /tariffs"]}," returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403"]},". If your application acts for a user with the Authorization Code grant, the tariff belongs to that user instead, even when your application is linked to an organisation. Only that user, through your application, can update or delete it, and a user token cannot update or delete your organisation's tariffs."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A tariff that belongs to a user, including one the user created in the ev.energy app, is private to them:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The user who created it, and any user it is assigned to, can read it."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An organisation can read it while it is the import or export tariff of one of the organisation's users, or was created by one. This lets you see the tariff your users are on, even when they set it up themselves."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Everyone else, including other users of your application, gets ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]},", and cannot assign it to a user."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"creating-a-tariff","__idx":4},"children":["Creating a tariff"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A tariff is described by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rate_periods"]},". Each period gives the rates for one day, and the months and weekdays that day applies to."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["months"]}," uses 1 for January to 12 for December."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["iso_weekdays"]}," uses 1 for Monday to 7 for Sunday."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Every combination of month and weekday must be covered by exactly one period."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Each period's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rates"]}," must cover the whole day, with no gaps or overlaps."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each rate has:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["start_time"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Local start time as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["HH:MM"]},", on the hour or half hour. Inclusive."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["end_time"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Local end time as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["HH:MM"]},", on the hour or half hour. Exclusive. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["00:00"]}," means midnight at the end of the day."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["price_minor_units_per_kwh"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Price per kWh in the smallest currency unit (pence, cents), as a decimal string such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"7.5\""]},", with up to 16 digits before the decimal point and 6 after. Negative prices are allowed."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["is_off_peak"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Optional. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," for off-peak rates. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["One rate in a day may cross midnight, such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["23:30"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["05:30"]},". A single rate whose ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["start_time"]}," equals its ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["end_time"]},", such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["00:00"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["00:00"]},", is a flat rate for the whole day."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Times are in the tariff's timezone, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timezone_name"]},". Clock changes are handled for you."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/tools/tariff-builder"},"children":["tariff builder"]}," builds ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rate_periods"]}," for you: start from a common shape such as day and night or weekday peak, set the hours of each daily schedule, choose which days use each one, and copy the request body. You can also paste a request body or a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs/{tariff_id}"]}," response into it to see and edit its rates."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-weekday-weekend-and-public-holiday-rates","__idx":5},"children":["Example: weekday, weekend and public holiday rates"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tariff has:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Weekdays: 7.5p off-peak from midnight to 07:00, and 24.5p for the rest of the day."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Weekends: 7.5p off-peak from midnight to 09:00, and 18p for the rest of the day."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Public holidays in England: 7.5p all day."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"sh","header":{"controls":{"copy":{}}},"source":"curl --request POST \\\n     --url https://api.ev.energy/v2/tariffs \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer example' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"name\": \"EV Saver\",\n  \"supplier_tariff_id\": \"EVS-2026-10\",\n  \"currency\": \"GBP\",\n  \"timezone_name\": \"Europe/London\",\n  \"user\": \"https://api.ev.energy/v2/users/user01HN2NJ9NMRZBXT1H6FT9N7735\",\n  \"rate_periods\": [\n    {\n      \"months\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n      \"iso_weekdays\": [1, 2, 3, 4, 5],\n      \"rates\": [\n        {\"start_time\": \"00:00\", \"end_time\": \"07:00\", \"price_minor_units_per_kwh\": \"7.5\", \"is_off_peak\": true},\n        {\"start_time\": \"07:00\", \"end_time\": \"00:00\", \"price_minor_units_per_kwh\": \"24.5\"}\n      ]\n    },\n    {\n      \"months\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n      \"iso_weekdays\": [6, 7],\n      \"rates\": [\n        {\"start_time\": \"00:00\", \"end_time\": \"09:00\", \"price_minor_units_per_kwh\": \"7.5\", \"is_off_peak\": true},\n        {\"start_time\": \"09:00\", \"end_time\": \"00:00\", \"price_minor_units_per_kwh\": \"18\"}\n      ]\n    }\n  ],\n  \"public_holiday_rates\": {\n    \"country\": \"GB\",\n    \"subdivision\": \"ENG\",\n    \"rates\": [\n      {\"start_time\": \"00:00\", \"end_time\": \"00:00\", \"price_minor_units_per_kwh\": \"7.5\", \"is_off_peak\": true}\n    ]\n  }\n}\n'\n","lang":"sh"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To give the summer months different rates, split ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["months"]}," across two or more periods, for example ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[4, 5, 6, 7, 8, 9]"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[1, 2, 3, 10, 11, 12]"]},", each with its own weekday periods."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"other-fields","__idx":6},"children":["Other fields"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Field"},"children":["Field"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Required"},"children":["Required"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["name"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The tariff's name as the user knows it. Up to 200 characters."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rate_periods"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Yes"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The weekly rates, as described above."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_holiday_rates"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Rates that replace the normal rates on public holidays. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["country"]}," is an ISO 3166-1 alpha-2 code, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subdivision"]}," is optional. When a holiday falls on a weekend and the country moves it to a weekday, as with UK bank holidays, only the weekday it moves to uses these rates."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["supplier"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["URL of the supplier from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /suppliers"]},". Defaults to a generic \"My supplier\"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["supplier_tariff_id"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your own or the supplier's reference for the tariff. Up to 100 characters."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["No"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["URL of a user you can access. The tariff is assigned to this user as part of the same request. Requires ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user:write"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["region"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Only if ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," is not sent"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["URL of the region the tariff applies to: a public reference region, or one your organisation created if your application is linked to one. Applications linked to an organisation can list both with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /regions"]},". Defaults to the user's region."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currency"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Only if ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," is not sent"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["ISO 4217 currency code. Defaults to the user's currency."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timezone_name"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Only if ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," is not sent"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["IANA timezone name from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /timezones"]},". Defaults to the user's timezone. Its offset from UTC must always be a whole or half hour."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"the-response","__idx":7},"children":["The response"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A successful request returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["201 Created"]}," with the tariff, in the same format as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs/{tariff_id}"]},". The response includes your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rate_periods"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_holiday_rates"]},". Periods with identical rates may be grouped differently from your request, but they describe the same prices."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Prices for the next 52 weeks are generated straight away, along with the four weeks before today. You can read them from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs/{tariff_id}/prices"]}," with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tariff:read"]}," scope. You don't need the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tariff:prices:read"]}," scope: it is only for prices licensed from third-party data providers, and a custom tariff's prices are never licensed."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/sandbox"},"children":["sandbox"]},", the request returns a sample tariff and nothing is created."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"assigning-the-tariff-to-a-user","__idx":8},"children":["Assigning the tariff to a user"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["There are two ways to make a custom tariff a user's import tariff."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["When creating it."]}," Send ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /tariffs"]}," body, as in the example above. This requires the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user:write"]}," scope as well as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tariff:write"]},"; without it the request fails with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403"]}," and nothing is written. The tariff is created and assigned in one step. If either part fails, nothing is written."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Later."]}," Update the user's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["default_location.tariff"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH /users/{user_id}"]},". This requires the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user:write"]}," scope."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"sh","header":{"controls":{"copy":{}}},"source":"curl --request PATCH \\\n     --url https://api.ev.energy/v2/users/user01HN2NJ9NMRZBXT1H6FT9N7735 \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer example' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"default_location\": {\n    \"tariff\": \"https://api.ev.energy/v2/tariffs/tari01JA7Q3ZKX2V8N5RB6TCWD4M9H\"\n  }\n}\n'\n","lang":"sh"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can assign a public tariff or one of your organisation's custom tariffs. You cannot assign another organisation's custom tariff."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you assign a tariff with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["POST /tariffs"]},", any price threshold the user has set is cleared, because it was set against their old prices."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"repricing-a-tariff","__idx":9},"children":["Repricing a tariff"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When the user's rates change, update the existing tariff with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH /tariffs/{tariff_id}"]}," rather than creating a new one. Send the complete new ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rate_periods"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]},", the first day the new rates apply:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"sh","header":{"controls":{"copy":{}}},"source":"curl --request PATCH \\\n     --url https://api.ev.energy/v2/tariffs/tari01JA7Q3ZKX2V8N5RB6TCWD4M9H \\\n     --header 'accept: application/json' \\\n     --header 'authorization: Bearer example' \\\n     --header 'content-type: application/json' \\\n     --data '\n{\n  \"effective_from\": \"2026-11-01\",\n  \"rate_periods\": [\n    {\n      \"months\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n      \"iso_weekdays\": [1, 2, 3, 4, 5, 6, 7],\n      \"rates\": [\n        {\"start_time\": \"23:30\", \"end_time\": \"05:30\", \"price_minor_units_per_kwh\": \"8.5\", \"is_off_peak\": true},\n        {\"start_time\": \"05:30\", \"end_time\": \"23:30\", \"price_minor_units_per_kwh\": \"26.1\"}\n      ]\n    }\n  ]\n}\n'\n","lang":"sh"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The rules for repricing are:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]}," is a date in the tariff's timezone. It must be after today and no more than two years after today. You cannot reprice today or the past, so charging that has already been costed is never changed. To change prices from tomorrow, send tomorrow's date."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rate_periods"]}," replaces all of the existing rates from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]},". Send ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public_holiday_rates"]}," again if the tariff should keep its holiday rates; leaving it out removes them from that date."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Prices before ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]}," are unchanged. Prices from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]}," onwards use the new rates."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Until ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs/{tariff_id}"]}," still shows the rates in force today. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GET /tariffs/{tariff_id}/prices"]}," shows the new prices for future dates straight away."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can change ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["name"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["supplier_tariff_id"]}," at any time, without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"sh","header":{"controls":{"copy":{}}},"source":"curl --request PATCH \\\n     --url https://api.ev.energy/v2/tariffs/tari01JA7Q3ZKX2V8N5RB6TCWD4M9H \\\n     --header 'authorization: Bearer example' \\\n     --header 'content-type: application/json' \\\n     --data '{\"name\": \"EV Saver (2027)\"}'\n","lang":"sh"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currency"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timezone_name"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["region"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["supplier"]}," cannot be changed after a tariff is created, and are ignored if sent. To change them, create a new tariff and assign it to the user."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Only the tariff's owner can update it. Updating a tariff you can see but do not own, such as a public tariff, returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"deleting-a-tariff","__idx":10},"children":["Deleting a tariff"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Delete a custom tariff you no longer need with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DELETE /tariffs/{tariff_id}"]},". This deletes the tariff and its prices, and returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["204 No Content"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"sh","header":{"controls":{"copy":{}}},"source":"curl --request DELETE \\\n     --url https://api.ev.energy/v2/tariffs/tari01JA7Q3ZKX2V8N5RB6TCWD4M9H \\\n     --header 'authorization: Bearer example'\n","lang":"sh"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A tariff that is still in use cannot be deleted. The request returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["409 Conflict"]}," with problem type ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tariff-in-use"]}," when:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["the tariff is any user's import or export tariff. Assign the user a different tariff first, then delete it;"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["the tariff has been used for charging, or is referenced by other historical records. Such a tariff cannot be deleted, because those records depend on its prices. Leave it in place."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"type\": \"https://api.ev.energy/v2/problems/tariff-in-use/\",\n  \"status\": 409,\n  \"title\": \"Tariff in use\",\n  \"detail\": \"This tariff is assigned to one or more users or referenced by historical records and cannot be deleted.\",\n  \"instance\": \"https://api.ev.energy/v2/tariffs/tari01JA7Q3ZKX2V8N5RB6TCWD4M9H\"\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"validation-errors","__idx":11},"children":["Validation errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If the request body is invalid, the API returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["422 Unprocessable Content"]}," with problem type ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["validation-failed-tariff"]},". Each invalid field is listed under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["field_errors"]},", as described in ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/errors"},"children":["Error responses"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"type\": \"https://api.ev.energy/v2/problems/validation-failed-tariff/\",\n  \"status\": 422,\n  \"title\": \"Request failed validation.\",\n  \"detail\": \"Error on fields: rate_periods\",\n  \"field_errors\": {\n    \"rate_periods\": [\"Every month and weekday must be covered exactly once. Not covered: month 12, iso_weekday 7.\"]\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Common causes are:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Problem"},"children":["Problem"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Fix"},"children":["Fix"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A month and weekday is not covered, or covered twice"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Check that every month 1–12 and weekday 1–7 appears in exactly one period."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A day's rates leave a gap or overlap"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Make each rate's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["end_time"]}," the next rate's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["start_time"]},", ending where the first rate starts."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A time is not on the hour or half hour"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Use times ending in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[":00"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[":30"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Unknown holiday country or subdivision"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Use an ISO 3166-1 alpha-2 country code and a subdivision that country recognises, or leave ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["subdivision"]}," out."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["region"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["supplier"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," not found"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Use a URL returned by the API to your application."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["region"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currency"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timezone_name"]}," missing"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Send them, or send ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["user"]}," so they can be taken from the user."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]}," is today, in the past, or more than two years ahead"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Use a date after today and within two years, in the tariff's timezone."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["timezone_name"]}," is offset from UTC by a quarter hour at some point in the year, such as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Asia/Kathmandu"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Australia/Eucla"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Pacific/Chatham"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Prices start on UTC half hours, so these timezones can't be used. Use a nearby timezone on a whole or half hour offset."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rate_periods"]}," sent without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["effective_from"]},", or the other way round"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Send both together."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The exact wording of error messages may change. Use the problem ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}," and the field names in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["field_errors"]}," to handle errors in code."]}]},"headings":[{"value":"Creating custom tariffs","id":"creating-custom-tariffs","depth":1},{"value":"When to create a custom tariff","id":"when-to-create-a-custom-tariff","depth":2},{"value":"Requirements","id":"requirements","depth":2},{"value":"Who can see a custom tariff","id":"who-can-see-a-custom-tariff","depth":2},{"value":"Creating a tariff","id":"creating-a-tariff","depth":2},{"value":"Example: weekday, weekend and public holiday rates","id":"example-weekday-weekend-and-public-holiday-rates","depth":3},{"value":"Other fields","id":"other-fields","depth":3},{"value":"The response","id":"the-response","depth":3},{"value":"Assigning the tariff to a user","id":"assigning-the-tariff-to-a-user","depth":2},{"value":"Repricing a tariff","id":"repricing-a-tariff","depth":2},{"value":"Deleting a tariff","id":"deleting-a-tariff","depth":2},{"value":"Validation errors","id":"validation-errors","depth":2}],"frontmatter":{"title":"Creating custom tariffs","seo":{"title":"Creating custom tariffs"}},"lastModified":"2026-10-14T10:57:20.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/howto/custom_tariffs","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}