PHPackages                             billythekid/punk-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. billythekid/punk-api

ActiveLibrary[API Development](/categories/api)

billythekid/punk-api
====================

PHP Wrapper for the Punk API - BrewDog DIY Dog beer recipes

2.0.1(2mo ago)460MITPHPPHP &gt;=8.3CI passing

Since Oct 15Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/billythekid/PunkApi)[ Packagist](https://packagist.org/packages/billythekid/punk-api)[ RSS](/packages/billythekid-punk-api/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (6)Dependencies (4)Versions (11)Used By (0)

PunkApi
=======

[](#punkapi)

[![Latest Stable Version](https://camo.githubusercontent.com/4a4c7e5c67fb7025c49c1e821a9007bad61627b373cfc1687789ddf2666bf363/68747470733a2f2f706f7365722e707567782e6f72672f62696c6c797468656b69642f70756e6b2d6170692f76657273696f6e)](https://packagist.org/packages/billythekid/punk-api)[![Total Downloads](https://camo.githubusercontent.com/a6af63a942cb097dcb0454b3fb0fc321d60c907107507f8abdc253a58764f59e/68747470733a2f2f706f7365722e707567782e6f72672f62696c6c797468656b69642f70756e6b2d6170692f646f776e6c6f616473)](https://packagist.org/packages/billythekid/punk-api)[![License](https://camo.githubusercontent.com/b7a5a16440196860dae248ea5911508129538b1ee7e9301bc3b43c58b0d631aa/68747470733a2f2f706f7365722e707567782e6f72672f62696c6c797468656b69642f70756e6b2d6170692f6c6963656e7365)](https://packagist.org/packages/billythekid/punk-api)

A PHP wrapper for the [PunkAPI](https://punkapi-alxiw.amvera.io/v3/) — all 415 BrewDog DIY Dog recipes.

The original PunkAPI by [Sam Mason](https://github.com/sammdec/punkapi) is no longer online. This wrapper now defaults to the **v3 API** hosted by [alxiw](https://github.com/alxiw/punkapi), and includes **bundled offline data** as a fallback so your code always gets results — even if the API is unreachable.

Requirements
------------

[](#requirements)

- PHP &gt;= 8.3
- Guzzle ^7.0 (installed automatically via Composer)

Installation
------------

[](#installation)

```
composer require billythekid/punk-api
```

Quick Start
-----------

[](#quick-start)

```
use billythekid\PunkApi;

$punkApi = PunkApi::create();

// Get beers (hits the live API, falls back to local data automatically)
$beers = $punkApi->getBeers();

// Check if the fallback was used
if ($punkApi->usedFallback()) {
    echo "Results came from bundled local data";
}
```

API Versions
------------

[](#api-versions)

The wrapper defaults to **v3** (recommended). The legacy v2 API is still supported but may be offline.

```
// v3 (default) — https://punkapi-alxiw.amvera.io/v3/
$punkApi = PunkApi::create();

// v2 (legacy) — https://api.punkapi.com/v2/
$punkApi = PunkApi::create('v2');
```

Offline Fallback
----------------

[](#offline-fallback)

All 415 beers from DIY Dog v8 are bundled in `data/beers.json`. When the live API can't be reached (connection timeout, DNS failure, etc.), the wrapper automatically filters and paginates from this local dataset. The same query parameters work identically whether hitting the API or the fallback.

Use `usedFallback()` to check which source was used:

```
$beers = $punkApi->named('punk')->getBeers();

if ($punkApi->usedFallback()) {
    // data came from local bundle
}
```

Methods
-------

[](#methods)

### Creating an Instance

[](#creating-an-instance)

```
$punkApi = new PunkApi();          // v3 by default
$punkApi = PunkApi::create();      // static constructor
$punkApi = PunkApi::create('v2');   // use legacy v2 API
```

### Querying Beers

[](#querying-beers)

```
getBeers()        // Returns an array of beer objects matching current params
getBeerById($id)  // Returns an array with a single beer by ID
getRandomBeer()   // Returns an array with a single random beer
```

### Building the Endpoint

[](#building-the-endpoint)

```
getEndpoint()     // Returns the URL that would be hit (does not make a request)
```

### Parameters

[](#parameters)

Use `addParams()` with an associative array, or the chainable helper methods:

ParameterTypeDescription`abv_gt`numberBeers with ABV greater than this`abv_lt`numberBeers with ABV less than this`ibu_gt`numberBeers with IBU greater than this`ibu_lt`numberBeers with IBU less than this`ebc_gt`numberBeers with EBC greater than this`ebc_lt`numberBeers with EBC less than this`beer_name`stringPartial name match (e.g. "punk" matches Punk IPA)`yeast`stringPartial yeast name match`hops`stringPartial hops name match`malt`stringPartial malt name match`food`stringPartial food pairing match`brewed_before`stringBeers brewed before this date (mm-yyyy)`brewed_after`stringBeers brewed after this date (mm-yyyy)`page`numberPage number for pagination`per_page`numberResults per page (default: 25 for v2, 30 for v3)`ids`stringComma-separated IDs for v3, pipe-separated for v2### Chainable Helper Methods

[](#chainable-helper-methods)

```
$punkApi->abvAbove(4)
    ->abvBelow(9)
    ->named('punk')
    ->getBeers();
```

All helpers: `abvAbove()`, `abvBelow()`, `ibuAbove()`, `ibuBelow()`, `ebcAbove()`, `ebcBelow()`, `named()`, `yeast()`, `brewedBefore()`, `brewedAfter()`, `hops()`, `malt()`, `food()`, `page()`, `perPage()`, `ids()`

The `ids()` method accepts an array of IDs or a string. It automatically formats them for the active API version (commas for v3, pipes for v2).

### Managing Parameters

[](#managing-parameters)

```
addParams(['abv_gt' => 4, 'beer_name' => 'punk'])  // Add params (chainable)
removeParams('beer_name', 'abv_gt')                  // Remove specific params (chainable)
clearParams()                                         // Remove all params (chainable)
```

Examples
--------

[](#examples)

```
use billythekid\PunkApi;

$punkApi = PunkApi::create();

// Get all beers with ABV between 4 and 9, named "punk"
$beers = $punkApi
    ->abvAbove(4)
    ->abvBelow(9)
    ->named('punk')
    ->getBeers();

// Same thing with addParams
$beers = $punkApi
    ->addParams(['abv_gt' => 4, 'abv_lt' => 9, 'beer_name' => 'punk'])
    ->getBeers();

// Get a specific beer
$beer = $punkApi->getBeerById(1);

// Get a random beer
$beer = $punkApi->getRandomBeer();

// Check the endpoint without making a request
$url = $punkApi->named('ipa')->getEndpoint();
// https://punkapi-alxiw.amvera.io/v3/beers?beer_name=ipa&page=1

// Get beers by multiple IDs
$beers = $punkApi->ids([1, 5, 10])->getBeers();
```

Changelog
---------

[](#changelog)

#### v 2.0.1

[](#v-201)

- Bugfix - `ids()` now normalizes separators automatically (pipes → commas on v3, commas → pipes on v2) so existing code passing pipe-separated strings continues to work

#### v 2.0.0

[](#v-200)

- **Breaking**: Removed API key parameter from constructor (v3 API requires no auth)
- **Breaking**: Requires PHP &gt;= 8.3
- Default API changed to v3 (`punkapi-alxiw.amvera.io`)
- Added offline fallback with bundled data (415 beers from DIY Dog v8)
- Added `usedFallback()` method
- `ids()` now uses commas for v3 (pipes still used for v2)
- Updated to Guzzle ^7.0 and PHPUnit ^13.0

#### v 1.1.2 - Mar 23, 2017

[](#v-112---mar-23-2017)

- Bugfix - not passing a param to `create()` threw an error

#### v 1.1.1 - Feb 10, 2017

[](#v-111---feb-10-2017)

- Bugfix - `perPage()` wasn't working properly
- Added more tests

#### v 1.1.0 - Feb 10, 2017

[](#v-110---feb-10-2017)

- Non-breaking update to use version 2 of the Punk API by default
- Added `ids()` method and `ids` parameter
- Added tests

#### v 1.0.0 - Oct 15, 2016

[](#v-100---oct-15-2016)

- Initial release

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance86

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~496 days

Recently: every ~829 days

Total

8

Last Release

70d ago

Major Versions

1.1.2 → v2.0.0.x-dev2026-04-20

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/330170?v=4)[Billy](/maintainers/billythekid)[@billythekid](https://github.com/billythekid)

---

Top Contributors

[![billythekid](https://avatars.githubusercontent.com/u/330170?v=4)](https://github.com/billythekid "billythekid (43 commits)")

---

Tags

beerbeers-matchingbrewdogphppunkapiwrapper

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/billythekid-punk-api/health.svg)

```
[![Health](https://phpackages.com/badges/billythekid-punk-api/health.svg)](https://phpackages.com/packages/billythekid-punk-api)
```

###  Alternatives

[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3661.2M46](/packages/tencentcloud-tencentcloud-sdk-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k496.1k33](/packages/neuron-core-neuron-ai)[avalara/avataxclient

Client library for Avalara's AvaTax suite of business tax calculation and processing services. Uses the REST v2 API.

528.3M7](/packages/avalara-avataxclient)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

252.5k](/packages/eslazarev-wildberries-sdk)[files.com/files-php-sdk

Files.com PHP SDK

2478.1k](/packages/filescom-files-php-sdk)[aimeos/prisma

A powerful PHP package for integrating media related Large Language Models (LLMs) into your applications

1942.4k4](/packages/aimeos-prisma)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
