A framework-agnostic fully typed JavaScript client for the Pi-hole API.
π Docs β’ π Getting Started β’ π API Reference β’ π Changelog
npm install pihole-js
pnpm add pihole-js
yarn add pihole-js
bun add pihole-jsimport PiHoleClient from 'pihole-js';
const client = new PiHoleClient({
baseUrl: 'http://pi.hole',
password: 'your-api-password',
userAgent: 'my-app/1.0',
});
const summary = await client.stats.getSummary();
const blocking = await client.dns.getStatus();
console.log(summary);
console.log(blocking);const client = new PiHoleClient({
baseUrl: 'http://pi.hole',
password: 'secret',
timeoutMs: 10_000,
userAgent: 'my-app/1.0',
});interface PiHoleClientOptions {
baseUrl: string;
password?: string;
timeoutMs?: number;
userAgent?: string;
fetch?: typeof globalThis.fetch;
sessionStore?: SessionStore;
}Auth:
client.auth.check()client.auth.login(credentials?)client.auth.logout()client.auth.getSessions()
Stats:
client.stats.getSummary()client.stats.getTopDomains(options?)client.stats.getDatabaseTopDomains(options)client.stats.getTopClients(options?)client.stats.getRecentBlocked(count?)client.stats.getDatabaseSummary(options)
History:
client.history.get()client.history.getClients(options?)client.history.getDatabase(options)client.history.getDatabaseClients(options)
Queries:
client.queries.list(options?)client.queries.getSuggestions()
DNS:
client.dns.getStatus()client.dns.setBlocking(blocking, timer?)client.dns.enable()client.dns.disable(seconds?)
Domains:
client.domains.list()client.domains.create(type, kind, payload)client.domains.update(type, kind, domain, payload)client.domains.delete(type, kind, domain)client.domains.allow(domain, comment?)client.domains.unallow(domain)client.domains.deny(domain, comment?)client.domains.undeny(domain)client.domains.allowRegex(pattern, comment?)client.domains.unallowRegex(pattern)client.domains.denyRegex(pattern, comment?)client.domains.undenyRegex(pattern)client.domains.search(domain, options?)
Groups:
client.groups.list()client.groups.get(name)client.groups.create(payload)client.groups.update(name, payload)client.groups.delete(name)
Clients:
client.clients.list()client.clients.get(client)client.clients.create(payload)client.clients.update(client, payload)client.clients.delete(client)client.clients.getSuggestions()
Lists:
client.lists.list(options?)client.lists.get(address, options?)client.lists.create(type, payload)client.lists.update(address, payload)client.lists.delete(address, type)
Config:
client.config.get(options?)client.config.patch(config, options?)client.config.getSection(element, options?)client.config.addArrayItem(element, value, options?)client.config.removeArrayItem(element, value, options?)
Network:
client.network.getDevices(options?)client.network.deleteDevice(deviceId)client.network.getGateway(options?)client.network.getRoutes(options?)client.network.getInterfaces(options?)
Info:
client.info.getSystem()client.info.getVersion()client.info.getMessages()client.info.getMessagesCount()client.info.deleteMessage(id)
Logs:
client.logs.getDnsmasq(options?)client.logs.getFtl(options?)client.logs.getWebserver(options?)
Teleporter:
client.teleporter.export()client.teleporter.import(archive, selection?)
Actions:
client.actions.updateGravity(options?)client.actions.restartDns()client.actions.flushLogs()client.actions.flushArp()client.actions.flushNetwork()
DHCP:
client.dhcp.getLeases()client.dhcp.deleteLease(ip)
Docs:
client.docs.getHtml()
PADD:
client.padd.getSummary()
If you provide a password, the client will authenticate automatically and reuse the returned Pi-hole session.
const client = new PiHoleClient({
baseUrl: 'http://pi.hole',
password: 'secret',
});
await client.stats.getSummary();For passwordless installs, omit the password:
const client = new PiHoleClient({
baseUrl: 'http://pi.hole',
});By default, each client instance keeps session data in memory.
import PiHoleClient, { MemorySessionStore } from 'pihole-js';
const sessionStore = new MemorySessionStore();
const client = new PiHoleClient({
baseUrl: 'http://pi.hole',
password: 'secret',
sessionStore,
});If you want to share sessions across client instances, provide your own store implementation that matches the SessionStore interface.
You can inject your own fetch implementation.
import PiHoleClient from 'pihole-js';
import fetch from 'node-fetch';
const client = new PiHoleClient({
baseUrl: 'http://pi.hole',
password: 'secret',
fetch,
});All request, authentication, timeout, and API errors are thrown as PiHoleError.
import PiHoleClient, { PiHoleError } from 'pihole-js';
const client = new PiHoleClient({
baseUrl: 'http://pi.hole',
password: 'secret',
});
try {
await client.stats.getSummary();
} catch (error) {
if (error instanceof PiHoleError) {
console.error(error.status);
console.error(error.code);
console.error(error.message);
}
}pnpm build
pnpm testContributions are always welcome!
Please ensure you run pnpm lint:fix before opening a pull request.
AGPL-3.0