Pi-hole API
The Pi-hole API is organized around REST. Our API has predictable resource-oriented URLs, accepts and returns reliable UTF-8 JavaScript Object Notation (JSON)-encoded data for all API responses, and uses standard HTTP response codes and verbs.
Most (but not all) endpoints require authentication. API endpoints requiring authentication will fail with code 401 Unauthorized if no key is supplied. See API Reference: Authentication for details.
Accessing the API documentation¶
The entire API is documented at http://pi.hole/api/docs and self-hosted by your Pi-hole to match 100% the API version your local Pi-hole has. Using this locally served API documentation is preferred. In case you don't have Pi-hole installed yet, you can also check out the documentation for all branches online, e.g., Pi-hole API documentation (branch master). Similarly, you can check out the documentation for a specific other branches by replacing master with the corresponding branch name.
API endpoints¶
An overview of all available endpoints is available at the API documentation page. The endpoints are grouped by their functionality.
JSON response¶
The form of replies to successful requests strongly depends on the selected endpoint, e.g.,
Example reply: Success
Resource: GET /api/dns/blocking
Response code: HTTP/1.1 200 OK
{
"blocking": true
}
Reply type
Object or Array
Fields
Depending on the particular endpoint
In contrast, errors have a uniform, predictable style to ease their programmatic treatment:
Example reply: Error (unauthorized access)
Resource: GET /api/domains
Response code: HTTP/1.1 401 Unauthorized
{
"error": {
"key": "unauthorized",
"message": "Unauthorized",
"hint": null
}
}
Reply type
Object
Fields
Key describing the error ("key": string)
This string may be used for internal categorization of error types
Examples for key are:
-
bad_requestPossible reason: Payload is invalid for this endpoint
-
database_errorPossible reason: Failed to read/write to the database
Human-readable description of the error ("message": string)
This string may be shown to the user for troubleshooting
Examples for messages are:
-
Could not read domains from database tablePossible reason: Database is not readable
-
No request body dataPossible reason: Payload is empty
-
Invalid request body dataPossible reason: Payload is not valid JSON
-
No "domain" string in body dataPossible reason: The required field
domainis missing in the payload
Additional data ("hint": [object|string|null])
The field hint may contain a JSON object or string. Its content depends on the error itself and may contain further details such as the interpreted user data. If no additional hint is available for this endpoint, null is returned.
Examples for a failed request with hint being set is (domain is already on this list):
{
"error": {
"key": "database_error",
"message": "Could not add to gravity database",
"hint": {
"argument": "abc.com",
"enabled": true,
"sql_msg": "UNIQUE constraint failed: domainlist.domain, domainlist.type"
}
}
}
HTTP methods used by this API¶
Each HTTP request consists of a method that indicates the action to be performed on the identified resource. The relevant standard is RFC 2616. Though, RFC 2616 has been very clear in differentiating between the methods, complex wordings are a source of confusion for many users.
Pi-hole's API uses the methods like this:
| Method | Description |
|---|---|
GET |
Read from resource |
POST |
Create a resource |
PATCH |
Update existing resource |
PUT |
Create or Replace a resource |
DELETE |
Delete existing resource |
Summarized details from RFC 2616, Scn. 9 (GET/POST/PUT/DELETE) and RFC 2068, Scn. 19.6.1.1 (PATCH)
GET¶
The GET method means retrieve whatever information (in the form of an entity) that is identified by the URI.
As GET requests do not change the state of the resource, these are said to be safe methods. Additionally, GET requests are idempotent, which means that making multiple identical requests must produce the same result every time until another method (POST or PUT) has changed the state of the resource on the server.
For any given HTTP GET, if the resource is found on the server, then the API returns HTTP response code 200 (OK) – along with the response body.
In case a resource is NOT found on server, then the API returns HTTP response code 404 (Not found). Similarly, if it is determined that GET request itself is not correctly formed then API will return HTTP response code 400 (Bad request).
POST¶
Use POST APIs to create new subordinate records, e.g., a file is subordinate to a directory containing it or a row is subordinate to a database table. WPOST methods are used to create a new resource into the collection of resources.
If a resource has been created on the origin server, the response will be 201 (Created).
Not all action performed using the POST method will result in a resource that can be identified by a URI. In such a case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.
Note that POST is neither safe nor idempotent, and invoking two identical POST requests typically results in an error.
PUT¶
Use PUT primarily to update existing records (if the resource does not exist, the API will typically create a new record for it). If a new record has been added at the given URI, or an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes are sent to indicate successful completion of the request.
PATCH¶
The PATCH method is similar to PUT except that the entity contains a list of differences between the original version of the resource identified by the Request-URI and the desired content of the resource after the `PATCH`` action has been applied. The list of differences is in a format defined by the media type of the entity (e.g., "application/diff") and MUST include sufficient information to allow the server to recreate the changes necessary to convert the original version of the resource to the desired version.
DELETE¶
As the name applies, DELETE APIs are used to delete records (identified by the Request-URI).
A successful response will be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.
DELETE operations are idempotent. If you DELETE a resource, it’s removed from the collection of resources. Repeatedly calling DELETE on that resource will not change the outcome – however, calling DELETE on a resource a second time may return a 404 (NOT FOUND) since it was already removed.
Example
Let’s list down a few URIs and their purpose to get better understanding when to use which method:
| Method + URI | Interpretation |
|---|---|
GET /api/groups |
Get all groups |
POST /api/groups |
Create a new group |
GET /api/groups/abc |
Get the group abc |
PUT /api/groups/abc |
Update the group abc |
DELETE /api/groups/abc |
Delete group abc |
Error handling¶
Pi-hole uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, missing authentication, etc.). Codes in the 5xx range indicate an error with Pi-hole's API (these are rare).
Some 4xx errors that could be handled programmatically include an error code that briefly explains the error reported:
| Code | Description | Interpretation |
|---|---|---|
200 |
OK |
Everything worked as expected |
201 |
Content Created |
Added a new item |
204 |
No Content |
Removed an item |
400 |
Bad Request |
The request was unacceptable, often due to a missing required parameter |
401 |
Unauthorized |
No session identity provided for endpoint requiring authorization |
402 |
Request Failed |
The parameters were valid but the request failed |
403 |
Forbidden |
The API key doesn't have permissions to perform the request |
404 |
Not Found |
The requested resource doesn't exist |
429 |
Too Many Requests |
Too many requests hit the API too quickly |
500, 502, 503, 504 |
Server Errors |
Something went wrong on Pi-hole's end (These are rare) |
We recommend writing code that gracefully handles all possible API exceptions. The Pi-hole API is designed to support this by standardized error messages and human-readable hints for errors.