Skip to main content

KFC

API key

Requests to the KFC API requires a KFC API key. This can be retrieved from the <script> tag at the end of the KFC homepage. Requests must come from a legitimate browser (determined by the user agent).

An example is shown below (formatted with whitespace for readability - the original is minified).

$ curl 'https://www.kfc.co.uk/ \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/111.0'
...
<script>
...
{
    "nutritionInformation": "https://brand-uk.assets.kfc.co.uk/nutrition-allergens.pdf"
}, "orderOriginAnnotations": {
    "fingerprintEndpointUrl": "https://fp.platform.kfcapi.com",
    "fingerprintApiKey": "E8uHaPCQYVV9mgTDF2pB",
    "fingerprintRegion": "eu"
}, "validation": {
    "regex": {
        "currency": "/^\\d+(\\.|\\,)\\d\\d$/",
        "phoneNumber": "/^0[1237]\\d{8,9}$/",
        "loyaltyCard": "/^\\d{8}-?\\d{3}$/",
        "email": "/^(([^\u0026lt;\u0026gt;()[\\]\\\\.,;:\\s@\"]+(\\.[^\u0026lt;\u0026gt;()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/",
        "basicPassword": "/^(?!.* )(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$/",
        "number": "/^-?\\d*(\\.\\d+)?$/",
        "dob": "/^\\d{4}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[12][0-9]|3[01])$/",
        "userName": "/^[A-Za-z][A-Za-z0-9 ]{1,}$/"
    }
}, "apiEndpoints": {
    "aggregatorv3": "/aggregators?city={city}\u0026lat={latitude}\u0026lng={longitude}\u0026postcode={postcode}"
}, "modeType": {
    "delivery": "Delivery",
    "clickAndCollect": "ClickAndCollect",
    "findRestaurant": "FindRestaurant"
}, "firebase": {
    "apiKey": "AIzaSyBfxHNPT4ZXUsZ53PYKRrJ3ihji6V4LgP4",
    "authDomain": "kfc-uki.firebaseapp.com",
    "databaseURL": "https://kfc-uki.firebaseio.com",
    "projectId": "kfc-uki",
    "storageBucket": "kfc-uki.appspot.com",
    "messagingSenderId": "370388072022",
    "appId": "1:370388072022:web:21b082985df244f42cedf7",
    "measurementId": "G-2ZFPMGWCJ5"
}, "careerUrl": "https://careers.kfc.co.uk/members/oauth/api", "enableBasketUpsell": true, "oneTrust": {
    "ID": "90b34549-608d-410c-ab2b-262c91ce2ae5"
}, "braze": {
    "sdkEndpoint": "sdk.fra-01.braze.eu",
    "sdkKey": "5ad9b4c0-4479-4fdd-a85a-509f317506a3"
}, "brandWebsiteUrl": "https://www.kfc.co.uk/", "nutritionLink": "https://brand-uk.assets.kfc.co.uk/nutrition-allergens.pdf", "deliveryFeeApiName": "Delivery fee", "serviceFeeApiName": "Service fee", "aggregator": true, "deliveryAddressMap": {
    "zoom": "18",
    "minZoom": "17",
    "maxZoom": "18",
    "maxDistanceInMeters": "200"
}, "orderHistory": {
    "OrderHistoryTile": {
        "backDays": "180",
        "maxOrdernumber": "20"
    }
}, "languageVersion": "189", "kfcDeliveryDistanceLimit": "200", "smallOrderFeeApiName": "Small order fee", "upsellsURL": "https://s3.eu-west-1.amazonaws.com/qa-kiosk.kfc.co.uk/upsells/prompts.json", "routesParams": {
    "productId": "pid",
    "categoryId": "cid",
    "localise": "localise",
    "localiseForDelivery": "delivery-localise",
    "localiseForCollect": "collect-localise"
}, "webClearBasketAfterMinutes": "360"
}
}
}
}, "page": "/", "query": {}, "buildId": "PoNtM0VQqWb9Q26Eh3ojt", "runtimeConfig": {
    "APP_TYPE": "website",
    "NEXT_API": "https://www.kfc.co.uk",
    "CMS_API": "https://uk.kfc-cms.com",
    "KFC_API": "https://prod.kfcapi.com/api/v1",
    "KFC_API_V3": "https://prod.kfcapi.com/api/v3",
    "KFC_API_OVERRIDES": "{}",
    "API_KEY": "siYAzKattmaIHSwMV9OJYtaoP8SRq",
    "APP_ENV_CODE": "UK-GB",
    "DELIVERY_GRAPHQL_API": "https://delivery.platform.kfcapi.com/graphql",
    "DELIVERY_GRAPHQL_API_KEY": "da2-g4p57iyxirctrfv7inygfmdtuq",
    "COUNTRY_CODE": "GB",
    "CODE_MARKET": "UK",
    "LANGCODE": "en",
    "GOOGLE_API_KEY": "AIzaSyApKSHDYIv9udfHvZB34WB6sAGZYojr97E",
    "RECAPTCHA_KEY": "6LcQBdoaAAAAAF8W2ucXcvQfO3wGQtrvpw2aVZRK",
    "ROBOT_TXT": "https://brand-uk.assets.kfc.co.uk/robots_GB.txt",
    "SITEMAP_URL": "https://brand-uk.assets.kfc.co.uk/sitemap_GB.xml",
    "ENVIRONMENT": "production",
    "KFC_SITES": "{\"GB\":\"https://www.kfc.co.uk\",\"IE\":\"https://www.kfc.ie\"}",
    "BUILD_NUMBER": "e6949418d76f97f221b04c997f433c81d7dbde8a",
    "ONETRUST_ID": "90b34549-608d-410c-ab2b-262c91ce2ae5",
    "DATADOG_APPLICATION_ID": "e6eccdc7-5923-492c-a098-06fb694f25f6",
    "DATADOG_CLIENT_ID": "pub898e007f540bf332315d09b8196beac6",
    "MPARTICLE_API_KEY": "us1-5867eed1788b2d4ca14fd7301f0629f5"
}, "isFallback": false, "customServer": true, "gip": true, "scriptLoader": []
}
</script>
</body>
</html>

Testing across a period of 15 minutes, multiple user agents, with no cache/cookies, reveals that this API key is fairly 'static'.

A regular expression to extract the API key from this page is shown below:

(?<="API_KEY":\s\")[a-zA-Z0-9]{29}(?=\")

KFC locations

The following API endpoint returns KFC locations based on a lookup string.

https://prod.kfcapi.com/api/v1/util/google/lookup?address=<LOCATION>&geotype=Google

Raw request

$ curl --compressed 'https://prod.kfcapi.com/api/v1/util/google/lookup?address=Gloucester&geotype=Google' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/111.0' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: en-GB,en;q=0.5' \
-H 'Accept-Encoding: gzip, deflate, br' \
-H 'Referer: https://www.kfc.co.uk/' \
-H 'x-api-key: siYAzKattmaIHSwMV9OJYtaoP8SRq' \
-H 'codemarket: UK' \
-H 'countrycode: GB' \
-H 'langcode: en' \
-H 'Origin: https://www.kfc.co.uk' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: cross-site' \
-H 'Connection: keep-alive' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache' \
-H 'TE: trailers'

Minimum required headers

Only the following headers are required:

  • codemarket
  • countrycode
  • x-api-key

Example values are shown in the curl request below.

$ curl --compressed 'https://prod.kfcapi.com/api/v1/util/google/lookup?address=Gloucester&geotype=Google' \
-H 'codemarket: UK' \
-H 'countrycode: GB' \
-H 'x-api-key: siYAzKattmaIHSwMV9OJYtaoP8SRq' 

Example response

[
  {
    "description": "Gloucester, UK",
    "matched_substrings": [
      {
        "length": 10,
        "offset": 0
      }
    ],
    "place_id": "ChIJz_Lr9vv9cEgRzxnoIZabcOw",
    "reference": "ChIJz_Lr9vv9cEgRzxnoIZabcOw",
    "structured_formatting": {
      "main_text": "Gloucester",
      "main_text_matched_substrings": [
        {
          "length": 10,
          "offset": 0
        }
      ],
      "secondary_text": "UK"
    },
    "terms": [
      {
        "offset": 0,
        "value": "Gloucester"
      },
      {
        "offset": 12,
        "value": "UK"
      }
    ],
    "types": [
      "locality",
      "political",
      "geocode"
    ]
  },
  {
    "description": "Gloucestershire, UK",
    "matched_substrings": [
      {
        "length": 10,
        "offset": 0
      }
    ],
    "place_id": "ChIJvWBKlTVTcEgRYidBWWOI7Dc",
    "reference": "ChIJvWBKlTVTcEgRYidBWWOI7Dc",
    "structured_formatting": {
      "main_text": "Gloucestershire",
      "main_text_matched_substrings": [
        {
          "length": 10,
          "offset": 0
        }
      ],
      "secondary_text": "UK"
    },
    "terms": [
      {
        "offset": 0,
        "value": "Gloucestershire"
      },
      {
        "offset": 17,
        "value": "UK"
      }
    ],
    "types": [
      "administrative_area_level_2",
      "political",
      "geocode"
    ]
  },
  {
    "description": "Gloucester Road, Kensington, London, UK",
    "matched_substrings": [
      {
        "length": 10,
        "offset": 0
      }
    ],
    "place_id": "EidHbG91Y2VzdGVyIFJvYWQsIEtlbnNpbmd0b24sIExvbmRvbiwgVUsiLiosChQKEgnzHEc5XQV2SBHWVE8x6AIEjBIUChIJNxJ0UPQPdkgRXik3cFTbw-0",
    "reference": "EidHbG91Y2VzdGVyIFJvYWQsIEtlbnNpbmd0b24sIExvbmRvbiwgVUsiLiosChQKEgnzHEc5XQV2SBHWVE8x6AIEjBIUChIJNxJ0UPQPdkgRXik3cFTbw-0",
    "structured_formatting": {
      "main_text": "Gloucester Road",
      "main_text_matched_substrings": [
        {
          "length": 10,
          "offset": 0
        }
      ],
      "secondary_text": "Kensington, London, UK"
    },
    "terms": [
      {
        "offset": 0,
        "value": "Gloucester Road"
      },
      {
        "offset": 17,
        "value": "Kensington"
      },
      {
        "offset": 29,
        "value": "London"
      },
      {
        "offset": 37,
        "value": "UK"
      }
    ],
    "types": [
      "route",
      "geocode"
    ]
  },
  {
    "description": "Gloucester Road Station, Gloucester Road, London, UK",
    "matched_substrings": [
      {
        "length": 10,
        "offset": 0
      }
    ],
    "place_id": "ChIJEVVNPV4FdkgREWjenJPqiBI",
    "reference": "ChIJEVVNPV4FdkgREWjenJPqiBI",
    "structured_formatting": {
      "main_text": "Gloucester Road Station",
      "main_text_matched_substrings": [
        {
          "length": 10,
          "offset": 0
        }
      ],
      "secondary_text": "Gloucester Road, London, UK"
    },
    "terms": [
      {
        "offset": 0,
        "value": "Gloucester Road Station"
      },
      {
        "offset": 25,
        "value": "Gloucester Road"
      },
      {
        "offset": 42,
        "value": "London"
      },
      {
        "offset": 50,
        "value": "UK"
      }
    ],
    "types": [
      "premise",
      "geocode"
    ]
  },
  {
    "description": "Gloucester Green, Oxford, UK",
    "matched_substrings": [
      {
        "length": 10,
        "offset": 0
      }
    ],
    "place_id": "ChIJ3TUITKTGdkgRF0rXBjwx5A8",
    "reference": "ChIJ3TUITKTGdkgRF0rXBjwx5A8",
    "structured_formatting": {
      "main_text": "Gloucester Green",
      "main_text_matched_substrings": [
        {
          "length": 10,
          "offset": 0
        }
      ],
      "secondary_text": "Oxford, UK"
    },
    "terms": [
      {
        "offset": 0,
        "value": "Gloucester Green"
      },
      {
        "offset": 18,
        "value": "Oxford"
      },
      {
        "offset": 26,
        "value": "UK"
      }
    ],
    "types": [
      "neighborhood",
      "political",
      "geocode"
    ]
  }
]