Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/jalmargyyk/netbox-ripe-updater/llms.txt

Use this file to discover all available pages before exploring further.

The updater service runs a Flask application that listens on a single HTTP port and exposes four routes. Three of them are read-only utilities — a health probe and two backup-browsing endpoints — while the fourth is the webhook ingestion endpoint that drives all RIPE synchronization. Understanding how each endpoint works helps you configure NetBox correctly, troubleshoot failed deliveries, and integrate the service with load balancers or monitoring tools.

GET /health

Returns a plain-text Ok response with HTTP 200. No authentication is required. This endpoint is intentionally minimal so that Docker health checks and load balancer probes can confirm the service is alive without sending credentials or a JSON body.
curl http://your-ripe-updater-host/health
# Ok
Response
StatusBodyMeaning
200 OKOkService is running
Use /health as the Docker HEALTHCHECK target and as the load balancer probe path. It adds no log noise because it runs at DEBUG level internally.

POST /update

Accepts NetBox webhook payloads and synchronizes the corresponding INETNUM or INET6NUM object in RIPE DB. This is the core endpoint of the service.

Authentication

If UPDATE_TOKEN is set in .env.updater, every request must carry an Authorisation header whose value matches the configured token exactly. NetBox sends the header as-is from the Additional Headers field of its webhook configuration.
Authorisation: Token <UPDATE_TOKEN>
The header name is Authorisation (British spelling), not the more common Authorization. NetBox and the updater both use this spelling — ensure your webhook configuration matches.
If the header is missing or does not match, the service returns 401 Unauthorized immediately.

Request format

The request body must be a valid NetBox webhook payload with Content-Type: application/json. Sending any other content type causes a 400 Bad Request response. Required fields in the payload
object_type
string
required
Must be "ipam.prefix". Any other value is rejected with 400.
event
string
required
The NetBox event type: "created", "updated", or "deleted". When event is "deleted", the RIPE object is removed regardless of ripe_report.
data.prefix
string
required
The prefix in CIDR notation, e.g. "203.0.113.0/24" or "2001:db8::/32".
data.custom_fields.ripe_report
boolean
required
Controls whether the prefix should exist in RIPE DB. Set to true to push the object; false to delete it.
data.custom_fields.ripe_template
string
The template name to use when building the RIPE object. Must match a key in your templates.json. Required when ripe_report is true.
data.custom_fields.ripe_netname
string
Optional override for the NETNAME attribute. When omitted, the template name is used as the NETNAME.
username
string
The NetBox username that triggered the event. Used in email reports; defaults to "None" if absent.

Behavior

ConditionAction
ripe_report = true and event != "deleted"Push (create or update) the INETNUM / INET6NUM object in RIPE DB
ripe_report = falseDelete the object from RIPE DB
event = "deleted" (any ripe_report)Delete the object from RIPE DB
Before any RIPE write, the updater backs up the current state of the object to S3 and queries NetBox for region, aggregate, and country data.

Example request

curl -X POST http://your-ripe-updater-host/update \
  -H "Content-Type: application/json" \
  -H "Authorisation: Token 123456abcdef" \
  -d '{
    "event": "updated",
    "object_type": "ipam.prefix",
    "username": "alice",
    "data": {
      "prefix": "203.0.113.0/24",
      "custom_fields": {
        "ripe_report": true,
        "ripe_template": "CLOUD-POOL",
        "ripe_netname": "EXAMPLE-CLOUD"
      }
    }
  }'

Response codes

StatusMeaning
204 No ContentSuccess — RIPE DB was updated or deleted
200 OKSkipped — prefix is a non-routed network (NotRoutedNetwork) or below the configured minimum size (ErrorSmallPrefix)
400 Bad RequestInvalid payload — wrong content type, missing object_type, or missing custom fields
401 UnauthorizedToken mismatch or missing Authorisation header
500 Internal Server ErrorRIPE API returned an error; check logs for details
A 200 response on a skipped prefix is intentional — the updater successfully processed the request and decided no RIPE action was needed. NetBox webhook delivery will mark these as successful.

GET /backups

Returns an HTML page listing all backup files stored in the configured S3 bucket. Protected by HTTP Basic Auth using UI_USER and UI_PASSWORD.
curl -u admin:password http://your-ripe-updater-host/backups
Each entry on the page links to the individual backup endpoint below. Backups are named after the prefix they represent, for example prefix_203.0.113.0_24.json. Response
StatusBodyMeaning
200 OKHTML pageBackup list rendered successfully
401 UnauthorizedMissing or wrong Basic Auth credentials

GET /backup/{name}

Returns the JSON content of a single named backup file. Protected by HTTP Basic Auth using the same UI_USER and UI_PASSWORD credentials.
curl -u admin:password \
  http://your-ripe-updater-host/backup/prefix_203.0.113.0_24.json
The response is the raw RIPE REST API JSON representation of the object at the time it was backed up. You can pipe this directly into a curl POST to restore the object manually:
curl -u admin:password \
  http://your-ripe-updater-host/backup/prefix_203.0.113.0_24.json \
  | curl --user "RIPE_API_USER:RIPE_API_PASS" \
         -X POST \
         -H "Content-Type: application/json" \
         --data @- \
         https://rest.db.ripe.net/ripe/inetnum
Response
StatusBodyMeaning
200 OKJSONBackup content
401 UnauthorizedMissing or wrong Basic Auth credentials

Error responses

All error responses return a plain-text body describing the problem. The most common causes are:
  • 401UPDATE_TOKEN is set but the Authorisation header is missing or wrong
  • 400 — wrong content type — the Content-Type header is not application/json
  • 400 — not a prefixobject_type is present but is not "ipam.prefix"
  • 400 — missing custom fieldsdata.custom_fields.ripe_report is absent from the payload
  • 500 — RIPE API rejected the object; the response body contains the raw exception; check application logs for the full RIPE error message

Known limitations

Edge cases that cause silent skips or failures in RIPE updates

FAQ

Answers to common configuration and operational questions

Build docs developers (and LLMs) love