This document aims to outline the differences between the Cloudflare API versions 1 (v1) and 4 (v4) and help you migrate from v1 to v4.
The API docs for v4 are always found at https://api.cloudflare.com/.
v1 used a single endpoint and triggered behavior based on the value of the a request parameter. All endpoints were POST requests regardless of the data requested or being modified.
v4 organizes API resources into namespaced URIs which GET, POST, PUT, PATCH, and DELETE requests dictate how information is interacted with.
The base URL for v1 operations was https://www.cloudflare.com/api_json.html. The base URL for v4 operations is https://api.cloudflare.com/client/v4.
For brevity, both base URLs are represented as $V1_URL and $V4_URL in this document’s examples.
GET requests are used to fetch data from the API. GET requests are considered idempotent and will never affect underlying data.
In general there are two types of GET requests:
Param | Type | Description |
---|---|---|
page |
integer | Which page of results to return |
per_page |
integer | How many results to return per page |
order |
string | Attribute name to order the responses by |
direction |
string | Either ASC or DESC |
POST requests are used when creating objects within the API. Complete well-formed JSON objects are expected in the request body.
If the request was successful, the created object is returned in the response’s result object along with any additional information (a generated id field, for example).
This is best exemplified when creating a zone. The minimum required payload is something similar to the following:
{ "name" : "example.com" }
However the complete zone object created looks more like:
{
"created_on": "2016-05-04T17:27:51.703294Z",
"development_mode": 0,
"id": "835e2f3260c0619b6833729d7bb51aec",
"meta": {
"custom_certificate_quota": 0,
"multiple_railguns_allowed": false,
"page_rule_quota": 3,
"phishing_detected": false,
"step": 4,
"wildcard_proxiable": false
},
"modified_on": "2016-05-04T17:27:51.768173Z",
"name": "example.com",
"name_servers": [
"lily.ns.cloudflare.com",
"matt.ns.cloudflare.com"
],
"original_dnshost": null,
"original_name_servers": [
"ns1.example.net",
"ns4.example.net",
"ns3.example.net",
"ns2.example.net"
],
"original_registrar": "example, inc.",
"owner": {
"email": "hello@example.com",
"id": "31f8757a9501fb0f5c1c29fb1277ad04",
"type": "user"
},
"paused": false,
"permissions": [
"#analytics:read",
"#billing:edit",
"#billing:read",
"#cache_purge:edit",
"#dns_records:edit",
"#dns_records:read",
"#lb:edit",
"#lb:read",
"#logs:read",
"#organization:edit",
"#organization:read",
"#ssl:edit",
"#ssl:read",
"#waf:edit",
"#waf:read",
"#zone:edit",
"#zone:read",
"#zone_settings:edit",
"#zone_settings:read"
],
"plan": {
"can_subscribe": true,
"currency": "USD",
"externally_managed": false,
"frequency": "",
"id": "0feeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"is_subscribed": true,
"legacy_id": "free",
"name": "Free Website",
"price": 0
},
"status": "pending",
"type": "full"
}
PUT requests are used when replacing existing objects within the API. Like POST, complete JSON objects are expected in the request body.
If the request was successful, the modified object is returned in the response’s result object.
PATCH requests are used to change one or more fields within an API object. Unlike POST and PUT requests, data objects may be incomplete. Only the fields provided will be affected.
If the request was successful, the complete modified object is returned in the response’s result object.
DELETE requests are used to delete objects within the API.
v1 used form-encoded data to send data into the API and JSON to represent data in responses. This requires extra work on both the client- and server-side for data translation back and forth.
v4 uses JSON to represent data in both requests and responses. It can be expected that when creating a Page Rule that the JSON object sent in the POST request will be nearly identical coming back in a GET request to that same object.
The response format is similar to that of v1’s response objects. A v1 response consists of four common fields: request, response, result, and msg:
{
"request": {},
"response": {},
"result": "success",
"msg": null
}
In v4, the response has be changed slightly. The inbound request is no longer echoed back out and the response field has been renamed to result. The errors and messages fields offer additional information about the state of the request and/or response. The result_info field will appear when results are potentially paginated.
{
"result": {},
"success": true,
"errors": [],
"messages": [],
"result_info": {
"page": 1,
"per_page": 20,
"count": 1,
"total_count": 200
}
}
v1 used two request parameters to authenticate requests: tkn and email.
v4 uses these same fields, however they are passed in via HTTP headers.
X-Auth-Email
replaces the email
field. It is your Cloudflare account email.X-Auth-Key
replaces the tkn
field. It is your API key and can be the same one used previously in v1.You can always find your API key in your Dashboard under Account Settings.
Every resource in the v4 API (Users, Zones, Settings, Organizations, etc.) can be identified with an ID field. This is a 32-byte string of hex characters ([a-f0-9]). ID values are usually captured during resource creation (POST requests) or when fetching entire collections (GET requests) of resources.
It’s important to emphasise that the IDs returned in v4 responses are no longer numeric as they were in v1.
You can always find the IDs for API resources by making a GET request to it’s corresponding collection endpoint. For example, to list all Zone objects, a GET request may be sent to $V4_URL/zones. All objects listed in the result array will contain an id field. These endpoints also have the advantage of supporting pagination and filtering.
v1’s stats requests are covered in the v4 Zone Analytics Dashboard request.
Before:
curl $V1_URL \
-d 'a=stats' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com' \
-d 'interval=20'
After:
curl -X GET $V4_URL'/zones/023e105f4ecef8ad9ca31a8372d0c353/analytics/dashboard?since=2015-01-01T12:23:00Z&until=2015-01-02T12:23:00Z'
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json'
The primary difference between v1 and v4 requests for Zone statistics is that the interval has been changed to a date range defined by the since and until query parameters. These can be absolute timestamps or numbers relative to the time of the request.
Note: The Zone ID used in the v4 example (023e105f4ecef8ad9ca31a8372d0c353) will be different from zone-to-zone. See the next section, Retreive the list of domains, for how to get these IDs for your zones.
Related Documentation:stats
Endpointv1’s zone_load_multi requests are covered in the v4 List Zones request.
Before:
curl $V1_URL \
-d 'a=zone_load_multi' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
After:
curl -X GET $V4_URL'/zones' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json'
The /zones endpoint lists multiple zones which may also be filtered by name or status. Pagination is also supported.
In addition to listing multiple zones, a single zone may also be loaded by concatenating the zone’s ID to the URL as shown in the Zone Details endpoint (/zones/:zone_identifier).
Related Documentationzone_load_multi
Endpointv1’s rec_load_all requests are covered in the v4 List DNS Records request.
Before:
curl $V1_URL \
-d 'a=rec_load_all' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com'
After:
curl -X GET '/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json'
The /zones/:zone_identifier/dns_records endpoint lists multiple DNS records which may also be filtered by type, name, and content. Pagination is also supported.
In addition to listing multiple DNS records, a single record may also be loaded by concatenating the records’s ID to the URL as shown in the DNS record details endpoint (/zones/:zone_identifier/dns_records/:identifier).
Related Documentationrec_load_all
EndpointBefore:
curl $V1_URL \
-d 'a=rec_new' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com' \
-d 'type=A' \
-d 'name=sub' \
-d 'content=1.2.3.4'
After:
curl -X POST '/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json' \
--data '{
"type": "A",
"name": "sub.example.com",
"content": "1.2.3.4"
}'
Related Documentation
Before:
curl $V1_URL \
-d 'a=rec_edit' \
-d 'id=9001' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com' \
-d 'type=A' \
-d 'name=sub' \
-d 'content=1.2.3.4' \
-d 'service_mode=1' \
-d 'ttl=1'
After:
curl -X PUT $V4_URL'/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json' \
--data '{
"type": "A",
"name": "sub.example.com",
"content": "1.2.3.4",
"proxied": true
}'
DNS records are updated by sending a PUT request to the /zones/:zone_identifier/dns_records/:identifier endpoint.
Related Documentationrec_edit
Endpointv1’s rec_delete requests are covered with the v4 Delete DNS record request.
Before:
curl https://www.cloudflare.com/api_json.html \
-d 'a=rec_delete' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com' \
-d 'id=9001'
After:
curl -X DELETE $V4_URL'/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json' \
Sending a DELETE request to the /zones/:zone_identifier/dns_records/:identifier endpoint will remove the DNS record from the zone.
Related Documentationrec_delete
EndpointThere is no direct analog to v1’s zone_check request as zone IDs are returned from other endpoints.
It is recommended to use v4’s List Zones endpoint to read zone IDs from the returned objects. It is also possible to filter by zone name by passing a name query parameter.
curl -X GET $V4_URL'/zones?name=example.org' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json'
Related Documentation
zone_check
EndpointThreat scores are no longer supported after v1.
Related Documentationip_lkup
Endpointv1’s zone_settings
requests are covered in the v4 Get all Zone
settings request.
Before:
curl $V1_URL \
-d 'a=zone_settings' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com'
After:
curl -X GET "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/settings" \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json'
Previously in v1, the settings were key/value pairs returned. v4 supports many
settings some of which have more complex data requirements than singular value.
Settings are JSON objects composed of id
, value
, editable
, and
modified_on
fields.
The id
fields are analogous to setting keys returned in v1. v4 also improves
these by making them more friendly to humans. For example, the Always Online
setting previously looked like:
"ob": 1
v4 represents this as:
{
"id": "always_online",
"value": "on",
"editable": true,
"modified_on": "2014-01-01T05:20:00.12345Z"
}
In addition to being able to list all settings bound to a zone, individual
settings may be queried with the /zones/:zone_identifier/settings/:name
endpoint. This same endpoint can be use to modify setting values (assuming
that the editable
field is true
) by issuing a PATCH request.
The next section outlines all settings in Section 4 of the v1 API docs. It should be noted that there are many more settings now available in v4.
Related Documentationzone_settings
EndpointAll zone settings in v4 follow the same URI convention:
/zones/:zone_identifier/settings/:name
. This endpoint can be used to fetch
the setting’s state (via a GET request) or modified (via a PATCH request).
For example, to fetch the minify
setting:
curl -X GET '/zones/023e105f4ecef8ad9ca31a8372d0c353/settings/minify' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json'
And to modify that same setting:
curl -X PATCH '/zones/023e105f4ecef8ad9ca31a8372d0c353/settings/minify' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json' \
--data '{
"value":{
"css": "off",
"html": "off",
"js": "off"
}
}'
Be sure to consult the v4 documentation for specific settings you wish to affect. A complete listing follows.
v1’s fpurge_ts
requests are covered in the v4 Purge all files
request.
Before:
curl $V1_URL \
-d 'a=fpurge_ts' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com' \
-d 'v=1'
After:
curl -X DELETE $V4_URL'/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H 'Content-Type: application/json' \
--data '{"purge_everything": true}'
The v4 /zones/:zone_identifier/purge_cache
endpoint allows for clearing a
zone’s cache. By sending "purge_everything": true
, the API will clear all
cache for the given zone. The next section describes how to use the same
endpoint to clear specific files.
fpurge_ts
Endpointv1’s zone_file_purge
requests are covered by the v4 Purge individual
files by URL and Cache-Tags request.
Before:
curl https://www.cloudflare.com/api_json.html \
-d 'a=zone_file_purge' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'z=example.com' \
-d 'url=http://www.example.com/style.css'
After:
curl -X DELETE $V4_URL'/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H "Content-Type: application/json" \
--data '{
"files": ["http://www.example.com/css/styles.css"],
"tags": ["some-tag", "another-tag"]
}'
The v4 /zones/:zone_identifier/purge_cache
is also used to clear specific
files from the Cloudflare cache. To keep API requests to a minimum, files
field accepts an array of file names to purge. A tags
array is also available
for enterprise zones and allows any file with matching Cache-tag
headers to
be purged. For more information on purging by Cache-Tag, we’ve written a
helpdesk article covers it in great detail.
zone_file_purge
Endpointv1’s wl
/ ban
/ nul
requests are handled by the v4 Create Access
Rule request.
Before:
curl $V1_URL \
-d 'a=wl' \
-d 'tkn='$API_KEY \
-d 'email='$API_EMAIL \
-d 'key=0.0.0.0' \
After:
curl -X POST $V4_URL'/zones/023e105f4ecef8ad9ca31a8372d0c353/firewall/access_rules/rules' \
-H 'X-Auth-Email: '$API_EMAIL \
-H 'X-Auth-Key: '$API_KEY \
-H "Content-Type: application/json" \
--data '{
"mode": "whitelist",
"configuration": {
"target": "ip",
"value": "0.0.0.0"
},
"notes": "This rule is on because of an event that occured on date X"
}'
Support for access rules has grown significantly in v4. Different modes change the firewall’s behavior allowing for blocking, whitelisting, triggering a JavaScript challenge (I Am Under Attack Mode) or presenting a CAPTCHA challenge page). Rules can target IP addresses (IPv4 or 6), address ranges, ASNs, and even countries. In addition to applying access rules at a zone-level, rules may also be set at a user- or organization-level.
Related Documentationwl
/ ban
/ nul
EndpointNow that you’ve migrated, here’s a quick look at all the new things you can do with v4 that you couldn’t do earlier with v1:
Everyone’s Internet application can benefit from using Cloudflare.
Pick a plan that fits your needs.