InfraRabbit provider feed, version 1

An open format for a hosting provider to publish its own prices as one JSON file. Anyone can read it, InfraRabbit included, without scraping your site.

Spec licence: CC BY 4.0. Current version: 1.0. Shaped with EDIS Global's feed (schema 2.0) as a starting point; this is an acknowledgement, not an endorsement by or of anyone.

Why publish a feed

How to publish

  1. Write one JSON file per location (or one file per provider with a plan list per location file; v1 keeps it to one location per file). Follow the schema; see the example.
  2. Serve it at a stable public URL of your own, over HTTPS, as application/json. Regenerate it whenever a price changes, and at least daily.
  3. Tell us the URL (next section). Publishing the URL and telling us is your permission to read it; nothing else is needed, and we read it no more than once a day.
  4. Check the file with the validator below before you tell us.

Rules of the format: state, never estimate. Leave out what you do not know; never write 0 for an unknown (0 means free). Prices are the ones you publish, in your own currency. Unknown fields are allowed and ignored, so you can add your own.

How to tell us

Write to inbox@infrarabbit.com with the feed URL, or use the corrections page if a number of ours differs from your feed. We read the feed, show the prices and date them from your generated_at.

Fields

Required fields are marked. Types follow JSON Schema; dates are ISO 8601; a TB is 1000 GB unless gb_per_tb says otherwise.

FieldRequiredTypeMeaning
schema_versionyesstringVersion of this spec the file follows: 1.0 for this version.
provideryesobjectWho publishes the feed.
provider.nameyesstringCompany or brand name.
provider.urlyesstringThe provider's website.
provider.contactstringWhere we can reach you about the feed: an email address or a URL.
generated_atyesstringWhen the file was generated, RFC 3339 date-time.
locationyesobjectThe location the plans below are sold in.
location.idyesstringYour stable identifier of the location, for example nl-ams.
location.countryyesstringISO 3166-1 alpha-2 country code, uppercase, for example NL.
location.citystringCity name.
location.display_namestringLocation name as shown on your site.
location.datacenterstringDatacenter or facility name, as you state it.
plansyesarrayThe plans sold in this location, with the prices as published.
plans[].idyesstringYour stable identifier for the plan (a product id or slug). Must not change when the price changes.
plans[].nameyesstringThe plan name as shown on your site.
plans[].urlyesstringPublic page of the plan on your site.
plans[].order_urlstringLink that starts the order for this plan.
plans[].vcpuyesintegerNumber of virtual CPU cores included.
plans[].vcpu_typeshared | dedicatedshared if cores are shared with other customers, dedicated if reserved for this plan.
plans[].cpu_modelstringCPU model or family, as you state it.
plans[].ram_gbyesnumberRAM in GB.
plans[].disk_gbyesnumberDisk size in GB.
plans[].disk_typestringDisk technology as you state it, for example NVMe, SSD, HDD.
plans[].traffic_tbnumberMonthly traffic included, in TB (1 TB = 1000 GB unless gb_per_tb says otherwise). Omit if unmetered or unknown; use traffic_unmetered for unmetered.
plans[].gb_per_tb1000 | 1024GB in one TB for traffic_tb. 1000 if omitted.
plans[].traffic_unmeteredbooleantrue if traffic is not metered (fair use still goes in the plan page).
plans[].traffic_countedin | out | in+outWhich direction counts against the allowance.
plans[].bandwidth_mbps_guaranteednumberBandwidth in Mbit/s that is guaranteed per VPS. Omit if only best effort.
plans[].port_speed_mbpsnumberPort speed in Mbit/s (a port speed is not a guarantee).
plans[].ipv4_includedintegerNumber of IPv4 addresses included.
plans[].ipv6_prefixstringSize of the IPv6 prefix included, for example /64. Omit if none or unknown.
plans[].priceyesobjectThe base price of the plan as published, for one billing period.
plans[].price.amountyesnumberThe price as published, in the currency below. 0 only when the plan or option is really free.
plans[].price.currencyyesstringISO 4217 currency code of the amount, for example EUR.
plans[].price.vat_includedyesbooleantrue if the amount includes VAT, false if VAT is added at checkout.
plans[].price.billing_periodyeshour | month | yearThe period the amount is charged for.
plans[].termsarrayLonger commitments with their own monthly price.
plans[].terms[].monthsyesintegerLength of the commitment in months.
plans[].terms[].price_per_monthyesnumberPrice per month on this term, in the currency and VAT basis of price.
plans[].terms[].setup_feenumberOne-time setup fee on this term, same currency as price.
plans[].setup_feenumberOne-time setup fee in the currency of price. Omit if unknown; 0 only if stated as free.
plans[].availabilityobjectStock state of the plan.
plans[].availability.statusyesin_stock | out_of_stock | unknownWhether the plan can be ordered now.
plans[].availability.checked_atstringWhen the status was last checked, RFC 3339 date-time.
plans[].end_of_sale_datestringDate (YYYY-MM-DD) after which the plan can no longer be ordered, if announced.
addonsarrayPriced options besides the plans.
addons[].typeyesextra_ipv4 | backups | snapshots | windows_licence | ddos | traffic_overage_per_tbWhat the add-on is.
addons[].namestringThe add-on name as shown on your site.
addons[].urlstringPublic page of the add-on.
addons[].priceyesobjectPrice as published. billing_period is once for one-time fees; traffic_overage_per_tb is the price per TB.
addons[].price.amountyesnumberThe price as published, in the currency below. 0 only when the plan or option is really free.
addons[].price.currencyyesstringISO 4217 currency code of the amount, for example EUR.
addons[].price.vat_includedyesbooleantrue if the amount includes VAT, false if VAT is added at checkout.
addons[].price.billing_periodyeshour | month | year | onceThe period the amount is charged for.
policiesobjectRules that apply to the plans in this feed.
policies.port_25open | blocked | on_requestOutbound SMTP on port 25.
policies.sla_percentnumberUptime promised in the SLA, in percent, for example 99.9.
policies.money_back_daysintegerDays in which an order can be refunded.
policies.aup_urlstringLink to the acceptable use policy.
changesarrayAnnounced future price changes. The most valuable optional field: it lets readers show a change before it takes effect.
changes[].effective_dateyesstringDate (YYYY-MM-DD) from which the new price applies.
changes[].plan_idyesstringThe id of the plan in plans[] that changes.
changes[].old_pricenumberThe price before the change, same currency, period and VAT basis as the plan price.
changes[].new_priceyesnumberThe price from effective_date, same currency, period and VAT basis as the plan price.
changes[].notestringShort reason or remark, for example the announcement.

Example

The same file as example.json:

{
  "schema_version": "1.0",
  "provider": {
    "name": "Example Hosting B.V.",
    "url": "https://www.example-hosting.test",
    "contact": "feeds@example-hosting.test"
  },
  "generated_at": "2026-11-13T06:00:00Z",
  "location": {
    "id": "nl-ams",
    "country": "NL",
    "city": "Amsterdam",
    "display_name": "Netherlands - Amsterdam",
    "datacenter": "Example DC1"
  },
  "plans": [
    {
      "id": "vps-s",
      "name": "VPS S",
      "url": "https://www.example-hosting.test/vps/s",
      "order_url": "https://my.example-hosting.test/order?plan=vps-s",
      "vcpu": 1,
      "vcpu_type": "shared",
      "cpu_model": "AMD EPYC 7543",
      "ram_gb": 2,
      "disk_gb": 40,
      "disk_type": "NVMe",
      "traffic_tb": 2,
      "traffic_counted": "in+out",
      "port_speed_mbps": 1000,
      "ipv4_included": 1,
      "ipv6_prefix": "/64",
      "price": {
        "amount": 4.5,
        "currency": "EUR",
        "vat_included": false,
        "billing_period": "month"
      },
      "terms": [
        {
          "months": 12,
          "price_per_month": 4.0,
          "setup_fee": 0
        }
      ],
      "setup_fee": 0,
      "availability": {
        "status": "in_stock",
        "checked_at": "2026-11-13T05:55:00Z"
      }
    },
    {
      "id": "vps-m",
      "name": "VPS M",
      "url": "https://www.example-hosting.test/vps/m",
      "vcpu": 4,
      "vcpu_type": "dedicated",
      "ram_gb": 8,
      "disk_gb": 160,
      "disk_type": "NVMe",
      "traffic_tb": 10,
      "gb_per_tb": 1000,
      "traffic_counted": "out",
      "bandwidth_mbps_guaranteed": 250,
      "port_speed_mbps": 1000,
      "ipv4_included": 1,
      "price": {
        "amount": 16,
        "currency": "EUR",
        "vat_included": false,
        "billing_period": "month"
      },
      "availability": {
        "status": "unknown"
      },
      "end_of_sale_date": "2027-06-30"
    }
  ],
  "addons": [
    {
      "type": "extra_ipv4",
      "price": {
        "amount": 2,
        "currency": "EUR",
        "vat_included": false,
        "billing_period": "month"
      }
    },
    {
      "type": "backups",
      "price": {
        "amount": 1.2,
        "currency": "EUR",
        "vat_included": false,
        "billing_period": "month"
      }
    },
    {
      "type": "traffic_overage_per_tb",
      "price": {
        "amount": 1,
        "currency": "EUR",
        "vat_included": false,
        "billing_period": "once"
      }
    }
  ],
  "policies": {
    "port_25": "on_request",
    "sla_percent": 99.9,
    "money_back_days": 14,
    "aup_url": "https://www.example-hosting.test/aup"
  },
  "changes": [
    {
      "effective_date": "2027-01-01",
      "plan_id": "vps-s",
      "old_price": 4.5,
      "new_price": 5.0,
      "note": "Announced 2026-11-01 on our blog."
    }
  ]
}

Validation

Post your file to the validator. It reads only what you send; it never fetches a URL, so there is no GET form with ?url=. Answers are JSON: valid and a list of errors, each with a path (a JSON pointer) and a message. At most 512 KB per file, rate limited like our other public requests.

curl -sS -X POST --data-binary @feed.json \
  -H "Content-Type: application/json" \
  https://infrarabbit.com/spec/provider-feed/validate

Status 200 means the file was read (see valid); 400 means it is not JSON; 413 means it is too large; 429 means slow down.

Badge

If you publish the feed, you can say so. Paste this text link on your site:

<a href="https://infrarabbit.com/spec/provider-feed">Prices published in InfraRabbit feed format v1</a>

Versioning and changelog

The version is in schema_version. Within version 1 we only add optional fields and values; a file that is valid today stays valid. A change that could break a valid file becomes version 2 at a new address (v2.schema.json); version 1 stays online.