This governmental bank offers free exchange rate API access. But while their specs mention neither limitations nor any requirements, in effect they seem to block:
- Server-side fetching from shared hosting – it gets a 404 error. But the PHP code below does work for me from a dedicated server and also from localhost server.
- Client-side fetching – it gets a CORS error, which I assume is due to not having a
Access-Control-Allow-Origin
header.
I’ve tried asking them about limitations which they might not have bothered to document, but they’re unresponsive. So is there any modification to the codes below (e.g. adding certain headers to stream_context_create
and fetch
) that might bypass either of this?
P.S.
Don’t be tempted to refer to
scraping from in between specific identifiable tags from xml as it discusses their previous (now obsolete) API.
The codes below try to retrieve JSON data from that API.
Server-side fetching
<?php
$url = "https://edge.boi.org.il/FusionEdgeServer/sdmx/v2/data/dataflow/BOI.STATISTICS/EXR/1.0/?c%5BDATA_TYPE%5D=OF00&startperiod=2024-09-20&endperiod=2024-09-20&format=sdmx-json";
$cparams = array(
'http' => array(
'ignore_errors' => true,
)
);
$context=stream_context_create($cparams);
$content = file_get_contents($url, context: $context);
echo '<a href="' . $url . '" target="_blank">' . $url . '</a>';
echo '<hr>';
echo '<pre>' . print_r($http_response_header, true) . '</pre>';
echo '<hr>';
if (function_exists('json_validate'))
echo "It's " . (json_validate($content) ? '' : 'NOT') . ' JSON';
else {
$json_data_formatted = json_decode($content);
echo "It's " . ((json_last_error() === JSON_ERROR_NONE) ? '' : 'NOT') . ' JSON';
}
echo '<hr>';
echo '<textarea rows=30 cols=150>' . $content . '</textarea>';
?>
Client-side fetching
(don’t try to run it here since this site blocks fetch
in general)
const url = "https://edge.boi.org.il/FusionEdgeServer/sdmx/v2/data/dataflow/BOI.STATISTICS/EXR/1.0/?c%5BDATA_TYPE%5D=OF00&startperiod=2024-09-20&endperiod=2024-09-20&format=sdmx-json";
// Update the link element
document.getElementById('link').href = url;
document.getElementById('link').textContent = url;
// Fetch the content
fetch(url)
.then(response => {
// Save the headers to display later
let headers = '';
for (let [key, value] of response.headers.entries()) {
headers += `${key}: ${value}n`;
}
document.getElementById('headers').textContent = headers;
// Check if the response is valid JSON
return response.text().then(text => {
try {
const jsonData = JSON.parse(text);
document.getElementById('json-status').textContent = "It's valid JSON";
document.getElementById('content').value = JSON.stringify(jsonData, null, 2); // Pretty print JSON
} catch (error) {
document.getElementById('json-status').textContent = "It's NOT JSON";
document.getElementById('content').value = text; // Show raw content if not JSON
}
});
})
.catch(error => {
document.getElementById('json-status').textContent = "Failed due to " + error;
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fetch API Example</title>
</head>
<body>
<a id="link" href="#" target="_blank">Link</a>
<hr>
<pre id="headers"></pre>
<hr>
<p id="json-status"></p>
<hr>
<textarea id="content" rows="30" cols="150"></textarea>
</body>
</html>