# Update DNS from a script when your IP changes Keep a record such as `home.example.com` pointing at a connection whose address changes. A small script finds your current address and changes the record only when it differs. ::: tip Using a router? Most routers can update DNS themselves. InfraNest has a built-in **Dynamic IP** feature for that, with a link your router calls. See [Dynamic IP on your router](https://infranest.io/docs/dynamic-ip-on-your-router). Use this recipe when you want a script, for example on a Raspberry Pi or in a container. ::: **Runnable code:** the code on this page, ready to clone and run, is in [`infranest-examples/examples/dynamic-dns`](https://github.com/InfraNest-Infrastructure-Organized/infranest-examples/tree/main/examples/dynamic-dns). CI runs it against the [sandbox](../sandbox.md). ## The token Make a token with **DNS → Write** only, in the organization that holds the zone. ## Find the zone and the record ```sh curl https://api.infranest.io/api/organizations/42/dns-zones \ -H "Authorization: Bearer $INFRANEST_TOKEN" -H "Accept: application/json" ``` Note the zone's `id`, then list its A records: ```sh curl "https://api.infranest.io/api/organizations/42/dns-zones/318/dns-records?type=A" \ -H "Authorization: Bearer $INFRANEST_TOKEN" -H "Accept: application/json" ``` Note the `id` of the record you want to keep up to date. ## The script ```sh #!/bin/sh # Updates one A record to this machine's public IPv4 address, only when it changed. set -eu API=https://api.infranest.io/api/organizations/42/dns-zones/318/dns-records/9021 current=$(curl -fsS https://api.ipify.org) stored=$(curl -fsS "$API" -H "Authorization: Bearer $INFRANEST_TOKEN" -H "Accept: application/json" | jq -r .value) if [ "$current" != "$stored" ]; then curl -fsS -X PUT "$API" \ -H "Authorization: Bearer $INFRANEST_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"value\":\"$current\",\"ttl\":300}" > /dev/null echo "Updated to $current" fi ``` Run it every five minutes, for example with cron: `*/5 * * * * /usr/local/bin/update-dns.sh`. - **A short TTL** (300 seconds here) makes the new address take effect quickly. The minimum is 60. - **Only changed addresses are sent**, so the script stays well inside the [rate limits](../tokens-and-scopes.md#rate-limits) and the zone's history shows real changes only. - **To see what would change first**, add `?dry_run=1` to the `PUT`. See [Retries and dry runs](../retries-and-dry-runs.md).