Cloudflare API and DNS
For this example we are using a Free Cloudflare account to manage our DNS records. If you don’t have one or your domain is hosted elsewhere you can either transfer it to Cloudflare or update your current providers Name Servers to point to Cloudflare.
Retrieve Zone ID
Once logged in click on the domain you want to use.

Then scroll down and locate the API section, now copy the Zone ID and keep it to hand.

Zone ID:
2ba5972166bcdf34935728843955554e
Create A Record
Now if not already created, click on DNS > Records on the left and add an A Record and set Proxy to OFF and TTL to 1 min

Generate Tokens
Next click in the top right of the screen and select My Profile

Create a Read Token
Now we are going to create 2 Tokens, a Read and Edit one. The first is required to get the Record ID and can be removed afterwards if required for security.
Click on Create Tokens

Then the first option Edit zone DNS

Now under permissions use Zone + DNS + Read. The Zone Resources can be a particular Zone if there are multiple or in this case we’ll just use All Zones.

On the next summery page we just confirm and click Create Token

Now we can see our Read Token, which we copy and make a note of with our other gathered info

Read API Token:
WYlmyM9-9xOSBUDue6_sCErhtvHsqv20nhwXylX7
Create an Edit Token
Next we repeat the process except this time we use Zone + DNS + Edit in the permissions section


Once we have our Edit Token we copy this too

Edit API Token:
5pXqw0U0ZL6GkahuDaBSwVbSc9tLRZYrUEQMRXiq
Retrieve Record ID
The last bit of information we need is the Record ID which we need to run a fetch command on the MikroTik (also possible via Curl on a Linux Machine). Use the following command in a terminal and add your Zone ID and Read API Token found previously.
/tool/fetch url="https://api.cloudflare.com/client/v4/zones/<ZONE ID>/dns_records" http-header-field="Authorization: Bearer <READ API TOKEN>" http-method=get output=user
/tool/fetch url="https://api.cloudflare.com/client/v4/zones/2ba5972166bcdf34935728843955554e/dns_records" http-header-field="Authorization: Bearer WYlmyM9-9xOSBUDue6_sCErhtvHsqv20nhwXylX7" http-method=get output=user
Once ran on the MikroTIk it will provide the following output:

Locate the info after “id”: for the relevant record which will be our Record ID. Copy this with the rest

Record ID:
79e287776ea742f6df0d16cd5073f6cc
Scripts
New we can populate our script. There will be a single script however it’s been broken up below to explain each section
Public IP Check
This part will first download the public IP address by using the fetch command and save it in a txt file named newIP.txt
Then it will check to see if there is an existing file for the current IP. This should only be required the first time the script us run but if the file is removed for whatever reason it will prevent the script from failing to run. If no file is found it will create a new one with the fetch command as was used to get the up-to-date IP and name it currentIP.txt
The last stage is to populate the 2 variables ($newIP & $currentIP) from the txt file contents then compare the 2. If the new one is different to the old one it will log that the IP has changed and update the currentIP.txt for the new IP address.
#Public IP Check
/tool fetch url="http://myip.dnsomatic.com/" mode=http dst-path=newIP.txt
#Check CurrentIP.txt exists
:if ([:len [/file find name=currentIP.txt]] = 0) do={
/tool fetch url="http://myip.dnsomatic.com/" mode=http dst-path=currentIP.txt
}
#Compare New and Existing IP addresses
:local currentIP [file get currentIP.txt contents];
:local newIP [file get newIP.txt contents];
#If different run update script
:if ($newIP != $currentIP) do={
#Log and Save new IP
:log info message="New Pubilc IP: $newIP"
/file set currentIP.txt contents=$newIP
Cloud Flare update
# Define variables
:local apiToken "***<Your API Token>***"
:local zoneID "***<Your Zone ID***"
:local recordID "***<Your Record ID>***"
:local hostname "***<Your DNS record>***"
:local ipAddress "$newIP"
# Validate variables
:if (($apiToken = "") || ($zoneID = "") || ($recordID = "") || ($hostname = "") || ($ipAddress = "")) do={
:log error "One or more variables are not set. Please configure the API token, Zone ID, Record ID, Hostname, and IP address."
:error "Script terminated due to missing variables."
}
# Set the API endpoint
:local url ("https://api.cloudflare.com/client/v4/zones/" . $zoneID . "/dns_records/" . $recordID)
:log info $url
# Prepare JSON payload
:local json "{\
\"type\": \"A\", \
\"name\": \"$hostname\", \
\"content\": \"$ipAddress\", \
\"ttl\": 3600, \
\"proxied\": false\
}"
# Send the request
/tool fetch url=$url http-method=put http-header-field="Authorization: Bearer $apiToken,Content-Type: application/json" http-data="$json" output=user
Complete Script
#Public IP Check
/tool fetch url="http://myip.dnsomatic.com/" mode=http dst-path=newIP.txt
#Check CurrentIP.txt exists
:if ([:len [/file find name=currentIP.txt]] = 0) do={
/tool fetch url="http://myip.dnsomatic.com/" mode=http dst-path=currentIP.txt
}
#Compare New and Existing IP addresses
:local currentIP [file get currentIP.txt contents];
:local newIP [file get newIP.txt contents];
#If different run update script
:if ($newIP != $currentIP) do={
#Log and Save new IP
:log info message="New Pubilc IP: $newIP"
/file set currentIP.txt contents=$newIP
# Define variables
:local apiToken "5pXqw0U0ZL6GkahuDaBSwVbSc9tLRZYrUEQMRXiq"
:local zoneID "2ba5972166bcdf34935728843955554e"
:local recordID "79e287776ea742f6df0d16cd5073f6cc"
:local hostname "chr.mikrotikmaster.app"
:local ipAddress "$newIP"
# Validate variables
:if (($apiToken = "") || ($zoneID = "") || ($recordID = "") || ($hostname = "") || ($ipAddress = "")) do={
:log error "One or more variables are not set. Please configure the API token, Zone ID, Record ID, Hostname, and IP address."
:error "Script terminated due to missing variables."
}
# Set the API endpoint
:local url ("https://api.cloudflare.com/client/v4/zones/" . $zoneID . "/dns_records/" . $recordID)
:log info $url
# Prepare JSON payload
:local json "{\
\"type\": \"A\", \
\"name\": \"$hostname\", \
\"content\": \"$ipAddress\", \
\"ttl\": 3600, \
\"proxied\": false\
}"
# Send the request
/tool fetch url=$url http-method=put http-header-field="Authorization: Bearer $apiToken,Content-Type: application/json" http-data="$json" output=user
}

Great website and Mikrotik resource. I am a longtime Miktotik admin and can’t read enough resources to completely master all functions; but this resource, you have provided sure hit the ball out of the park with the nuts and bolts… I have been struggling with the scripting nomenclature for a couple of years; and your detailed advice and guidance, by it self, is PRICELESS… and you just published as well… Thank you!
We do private IT engagement and complete IT management for rural coastal Eastern NC. I will absolutely be back and your site has been flagged as a great resource.
Thanks for your feedback, happy to help!
I did everything, but probably something wrong and i got it: executing script script1 from winbox failed, please check it manually
That means there’s an error in your script. Can you share your script (omitting any keys/passwords) and I’ll review it for you?
I also face same issue
I have found an error in the script and have corrected it. Let me know if you’re still having issues.
I have found an error in the script and have corrected it. Let me know if you’re still having issues.
Hello, thank you very much for the script. I have an error with the website where it obtains the IP, looking at the website in Chrome sometimes it tells me (429 Too Many Requests), could it be done through another website?
I’ve not had this issue, what frequency are you running the script? There are several others that can be used but one I’ve tested with a MikroTik script is http://ifconfig.me/ip