#๐Ÿ”’ Problem posting data to the CMA Fuelfinder API

35 messages ยท Page 1 of 1 (latest)

frail goblet
#

I am trying to write a Python app to post fuel price data to the Fuelfinder API (https://www.register-fuel-finder-scheme.service.gov.uk/).

The price submission API reference is here (https://stg.developer.fuel-finder.ics.gov.uk/apis-mft/submit-fuelprice/docs?operationId=submitFuelPrices) and I have attached a screenshot.

As this post is quite long I have used a pastebin...

https://paste.pythondiscord.com/3MBA

I would be eternally grateful if anyone could help me to figure this out. I am reasonably new to Python and this is the first time I have attempted to use an API.

full warrenBOT
#

@frail goblet

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

ionic igloo
#

Hmm interesting API - wasn't aware of this before, so thanks!

In order to use the API, you need to get a token via OAuth and send it in the HTTP headers.
It seems submitting data is only for organisations rather than public use though. Do you have a:

A motor fuel trader registered GOV.UK One Login to access the API

frail goblet
#

yes, I have all the required credentials, and can get a token succcessfully. The 'only' issue I have is the actual submission

ionic igloo
#

Ah okay great! My bad, I should've read your pastebin first

Only differences I notice between yours and the sample payload is the site_id and timestamp formats (assuming the comments are examples):

Sample:

"site_id": "gcpvj0duq533",
"price_submission_timestamp": "2025-10-28 11:53:15",

Yours:

 "site_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
 "price_submission_timestamp": "2025-11-30T11:33:59Z",
#

I'm not sure if the site_id is usually a UUIDv4 or something similar to their example, as I don't have an account for this, but it may be worth trying the timestamp without the TZ (gtf.get_fuelfinder_timestamp)

frail goblet
#

Thank you. I'm slightly confused as my payload is:
{
"source_type": "API",
"stations": [
{
"site_id": "************",
"price_submission_timestamp": "2026-01-22 13:41:00",
"price_change_effective_timestamp": "2026-01-22 13:41:00",
"reported_within_30_min": true,
"prices": [
{
"fuel_type": "E10",
"price": 137.9
},
{
"fuel_type": "B7",
"price": 123.7
}
]
}
]
}

The values you mention are commented out in my code

#

which for me looks identical to the payload in the documentation... #baffled

ionic igloo
#

Hmm that's interesting, definitely seems to match the example...
Only things I can think of at the moment are to double-check the site_id and valid fuel types.

Other thing I notice is that the request body schema of the docs for that endpoint doesn't mention reported_within_30_min, but the example does:

#

Given the error message is

Request payload contains one or more invalid fields
I'd interpret that to mean one the fields is invalid rather than the values, so maybe try without the reported_within_30_min field?

frail goblet
#

yeah, sounds like a reasonable shout, I'll give that a go...

#

sadly that didnt help:

{
"source_type": "API",
"stations": [
{
"site_id": "***********",
"price_submission_timestamp": "2026-01-22 15:26:18",
"price_change_effective_timestamp": "2026-01-22 15:26:18",
"prices": [
{
"fuel_type": "E10",
"price": 137.9
},
{
"fuel_type": "B7",
"price": 123.7
}
]
}
]
}

Status: 400
Response: {"success":false,"data":{"success":false,"data":{"success":false,"statusCode":400,"error":["Request payload contains one or more invalid fields."]},"message":["Request payload contains one or more invalid fields."],"error":{"code":400,"details":["Request payload contains one or more invalid fields."]}},"message":{"code":400,"details":["Request payload contains one or more invalid fields."]},"error":{"code":400,"details":{"code":400,"details":["Request payload contains one or more invalid fields."]}}}

ionic igloo
#

Ah man that sucks. Usually I'd just blame the government for making a poorly documented API at this point haha, but that's not super helpful.

The docs also show url and service in the body schema which seems very weird to me:

frail goblet
#

aha! I spotted fuel_grade_availability in the screenshot you sent... I dont know what the value should be though, however the error seems to do with the data that is present rather than the data that is not present?

#

oh yes, this government thing is pretty rubbish - including the support!

#

incidentally where did you find your screenshot that doesnt show reported_within_30_min and does show fuel_grade_availability? I cant see that on the gov site??

ionic igloo
#

It doesn't say that fuel_grade_availability is required though...

frail goblet
#

wierd, it doesnt seem expandable for me. Maybe a need to lie down!

ionic igloo
#

Try clicking specifically the payload > above "required" to expand?

frail goblet
#

Thanks!... That was a link blush definately need that lie down, but my head is too sore after banging it against the wall all day!

ionic igloo
#

Haha I don't blame you

#

What if the payload needs to be:

{
  url: "https://stg.fuel-finder.ics.gov.uk/api/v1/pfs/",
  service: "fuel-prices",
  payload: {
    source_type: "API",
    ...
  }
}
```or something like that? Unsure on the values, but that's what the schema seems to suggest the structure should be
frail goblet
#

Not sure, do you mean change

{
"source_type": "API",
"stations": [
{
"site_id": "***********",
"price_submission_timestamp": "2026-01-22 15:26:18",
"price_change_effective_timestamp": "2026-01-22 15:26:18",
"prices": [
{
"fuel_type": "E10",
"price": 137.9
},
{
"fuel_type": "B7",
"price": 123.7
}
]
}
]
}

to this

{
url: "https://stg.fuel-finder.ics.gov.uk/api/v1/pfs/",
service: "fuel-prices",

payload: 
{
  "source_type": "API",
  "stations": [
    {
      "site_id": "***********",
      "price_submission_timestamp": "2026-01-22 15:26:18",
      "price_change_effective_timestamp": "2026-01-22 15:26:18",
      "prices": [
        {
          "fuel_type": "E10",
          "price": 137.9
        },
        {
          "fuel_type": "B7",
          "price": 123.7
        }
      ]
    }
  ]
}

}

IDK...

#

how do I refactor this to include your suggestion? Apologies if this is a dumb question.

def submit_prices(access_token):
data = {
"source_type": "API",
"stations": [
{
"site_id": FUEL_FINDER_ID,
"price_submission_timestamp": gtf.get_fuelfinder_timestamp(),
#"price_submission_timestamp": "2025-11-30T11:33:59Z",
"price_change_effective_timestamp": gtf.get_fuelfinder_timestamp(),
#"price_change_effective_timestamp": "2025-11-30T11:33:59Z",
"reported_within_30_min": True,
"prices": [
{"fuel_type": "E10", "price": 137.9},
{"fuel_type": "B7", "price": 123.7}
]
}
]
}

ionic igloo
#

Yeah that's what I mean, but no idea if it'd work haha...

def submit_prices(access_token):
  data = {
    "url": "https://stg.fuel-finder.ics.gov.uk/api/v1/pfs/",
    "service": "fuel-prices",
    "payload": {
      "source_type": "API",
      "stations": [
        {
          "site_id": FUEL_FINDER_ID,
          "price_submission_timestamp": gtf.get_fuelfinder_timestamp(),
          "price_change_effective_timestamp": gtf.get_fuelfinder_timestamp(),
          "prices": [
            {
              "fuel_type": "E10",
              "price": 137.9
            },
            {
              "fuel_type": "B7",
              "price": 123.7
            }
          ]
        }
      ]
    }
  }
  ...
#

@frail goblet - apologies for late reply. Pinging in case you don't see this

#

Try this with your original code...
Though I notice you have it on line 81 and 98 differently so who knows

frail goblet
#

Thank you and excellent spot, although lines 89 - 106 are redundant due to the return on line 88. I have now removed those lines! the other requests.post use json rather than data.

Also, I removed the Content-Type header (thanks for that info) but neither step has made any difference! Still the same response ๐Ÿ™

#

I will see if I can make any progress by trying to include the url and or service parameters in the body...

frail goblet
#

hmmm it didnt much like that ๐Ÿ™

PAYLOAD: {
"url": "https://stg.fuel-finder.ics.gov.uk/api/v1/pfs/",
"service": "fuel-prices",
"payload": {
"source_type": "API",
"stations": [
{
"site_id": "************",
"price_submission_timestamp": "2026-01-22 17:30:31",
"price_change_effective_timestamp": "2026-01-22 17:30:31",
"prices": [
{
"fuel_type": "E10",
"price": 137.9
},
{
"fuel_type": "B7",
"price": 123.7
}
]
}
]
}
}
HEADERS: {'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJraW5kIjoic2VjcmV0IiwiY2xpZW50X2lkIjoiWjljNzRXTXBkTlk2TXppNnF1bTA5VDZXYkJYSldFcngiLCJtZnRfaWQiOiIzYWU0NTlmOS05YjY5LTQzNWYtOGM1ZS1hZGRmMzUxZDc5ZjgiLCJzdWIiOiJaOWM3NFdNcGROWTZNemk2cXVtMDlUNldiQlhKV0VyeCIsImF1ZCI6Im9hdXRoIiwiaWF0IjoxNzY5MTAzMDMyLCJleHAiOjE3NjkxMDY2MzJ9.NQYadcBDNd1zyrQCMdpqHO_YlF--qYUM-EhpHp_jRO8'}
Status: 400
Response: {"success":false,"data":{"success":false,"data":{"success":false,"statusCode":400,"error":["Invalid field 'url' found at root level","Invalid field 'service' found at root level","Invalid field 'payload' found at root level"]},"message":["Invalid field 'url' found at root level","Invalid field 'service' found at root level","Invalid field 'payload' found at root level"],"error":{"code":400,"details":["Invalid field 'url' found at root level","Invalid field 'service' found at root level","Invalid field 'payload' found at root level"]}},"message":{"code":400,"details":["Invalid field 'url' found at root level","Invalid field 'service' found at root level","Invalid field 'payload' found at root level"]},"error":{"code":400,"details":{"code":400,"details":["Invalid field 'url' found at root level","Invalid field 'service' found at root level","Invalid field 'payload' found at root level"]}}}

full warrenBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.