# Digital Filter Designer: IIR & FIR Filters, C Code (`jumblemog/digital-filter-designer`) Actor

Design lowpass, highpass, bandpass, bandstop and notch filters from plain text: Butterworth, Chebyshev, elliptic, Bessel or FIR (window, Kaiser, Parks-McClellan). Coefficients, measured response and C/Python/MATLAB code. For AI agents.

- **URL**: https://apify.com/jumblemog/digital-filter-designer.md
- **Developed by:** [Jumble Mog](https://apify.com/jumblemog) (community)
- **Categories:** AI, Automation, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Digital Filter Designer: IIR & FIR Filters, C Code

**Design a digital filter by describing it.** Type `lowpass 100 Hz, fs 1 kHz, 4th order Butterworth` or `FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple`. You get back:

- **The coefficients**: second-order sections (the stable way to run an IIR filter), b and a, zeros, poles and gain, or the FIR taps.
- **Ready-to-paste code** in C (a biquad cascade or an FIR with a circular buffer), Python (SciPy, whole recordings or block by block) and MATLAB/Octave.
- **The response as measured**: -3 dB points, gain at the cutoff, passband ripple, stopband attenuation, group delay in samples and ms, linear phase, stability and the largest pole radius.
- **A chart**: magnitude response with your specs drawn in, group delay, impulse response, and poles and zeros on the unit circle.

It also:

- **Finds the order or length for you**: give the passband edge, the stopband edge, the ripple and the attenuation, and you get the lowest IIR order or the shortest FIR that meets them.
- **Checks fixed point**: round the coefficients to 16 bits (or any width from 4 to 32) and see the Q format, the integers, and whether the filter still works.
- **Filters your data**: pass a signal and get it back filtered, causally or with zero phase.

It's made for:

- Embedded and firmware developers putting a filter on a microcontroller or DSP.
- Audio, sensor, biomedical (ECG, EEG) and vibration engineers.
- Students checking filter-design homework.
- AI agents that need correct coefficients instead of guessed ones.

![A 111-tap Parks-McClellan lowpass designed by this Actor for 48 kHz audio: the magnitude response meeting 0.5 dB of passband ripple and 60.7 dB of stopband attenuation from 6 kHz, a flat 1.15 ms group delay, the symmetric impulse response, and its zeros on the unit circle](https://api.apify.com/v2/key-value-stores/Km5b4PG3kYHdZSb1E/records/digital-filter-designer-example.png?signature=1lInzafP5pUWprqHxS86U)

### What it does

#### Filters it designs

- **Bands**: lowpass, highpass, bandpass, bandstop, notch and peak (resonator).
- **IIR families**:
  - Butterworth (maximally flat).
  - Chebyshev I (passband ripple) and Chebyshev II (stopband ripple).
  - Elliptic (the sharpest for a given order).
  - Bessel (the flattest group delay).
- **FIR methods**:
  - Windowed sinc, with Hamming, Hann, Blackman, Blackman-Harris, Nuttall, flat-top, Bartlett or rectangular windows.
  - Kaiser window, with the length and β found from the attenuation and the transition width.
  - Parks-McClellan equiripple, the shortest FIR for a given spec.
  - Least squares.
- **Notch and peak** biquads, by Q or bandwidth.

#### Writing filters

Most specs fit in one line:

- **Sample rate**: `fs 1 kHz`, `sample rate 48000`, `sampled at 250 Hz`, or a trailing `at 8 kHz`.
- **Order or length**: `4th order`, `order 6`, `101 taps`.
- **Specs**: `1 dB ripple`, `60 dB attenuation`, `40 dB down at 200 Hz`, `stopband 6 kHz`, `transition 1 kHz`.
- **Family or method**: `Butterworth`, `Chebyshev`, `Chebyshev II`, `elliptic`, `Bessel`, `FIR`, `Kaiser`, `equiripple`, `Hamming`.

Objects work too, with the same fields named. Without a sample rate, frequencies like `lowpass 0.2` are read as fractions of the Nyquist frequency.

#### Finding the order

When you give the stopband edge (or a transition width) and the attenuation, the order or length is found for you:

- **IIR**: the lowest order that keeps the passband within the ripple and the stopband the given number of dB down.
- **Kaiser FIR**: the length and β from Kaiser's formula.
- **Equiripple and least-squares FIR**: the shortest length that meets both specs. It starts from an estimate, checks the result, and lengthens it until both specs are met.

#### Fixed point

Add `coefficientBits` and the coefficients are rounded to signed fixed point. You get:

- The Q format (for example Q1.14 for 16 bits) and the integer coefficients.
- Whether the rounded filter is still stable.
- How far the passband moved, and the stopband attenuation that's left.

The chart overlays the rounded response.

#### Filtering a signal

Add `signal` (a list of numbers) and the filtered signal comes back. Set `zeroPhase` to filter forward and backward, with no delay. Up to 1,000,000 samples. Results over 10,000 samples come as a CSV file.

### How to use it

1. Write **Filters**, one per line, such as `highpass 0.5 Hz, fs 250 Hz, 2nd order Butterworth`. The form has examples.
2. Optionally set a **Default sample rate** or **Fixed-point coefficient bits** for all of them.
3. Click **Start**. Each filter is a row in the results, with its summary, chart, code and report.

### Examples

All of these ran on this Actor, and the numbers are from the results.

| Filter | Result |
|---|---|
| `lowpass 100 Hz, fs 1 kHz, 4th order Butterworth` | -3 dB at 99.94 Hz (the same sections as SciPy's `butter`), group delay 4.02-6.53 ms in the passband, stable |
| `lowpass 100 Hz, fs 1 kHz, 0.5 dB ripple, 40 dB down at 200 Hz` | Order 8 Butterworth: 0.498 dB ripple, 46.8 dB at 200 Hz, -3 dB at 112.9 Hz |
| `bandpass 300-3400 Hz, fs 8 kHz, 1 dB ripple, 40 dB down at 200 Hz and 3.8 kHz, elliptic` + 16 bits | Order 8 (4 per edge): 1 dB ripple, 40 dB stopband. In Q1.14 it's still stable and the passband moves by 0.006 dB |
| `FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple` | 111 taps (109 fall short): 0.472 dB ripple, 60.7 dB stopband, linear phase, 55 samples (1.15 ms) of delay |
| `FIR lowpass 5 kHz, fs 48 kHz, transition 1 kHz, 60 dB attenuation, kaiser` | 176 taps, β 5.65: 59.7 dB stopband, 0.015 dB ripple |
| `lowpass 1 kHz, fs 44.1 kHz, 60 dB down at 2 kHz, Chebyshev II` | Order 7: 0.98 dB ripple, 60 dB stopband, -3 dB at 1.081 kHz |
| `notch 50 Hz, Q 20, fs 1 kHz` | A full null at 50 Hz, -3 dB at 48.76 and 51.27 Hz |

The tests check that:

- The designs match SciPy.
- The automatic orders are the lowest that meet the specs, and the equiripple length is the shortest.
- A notch's -3 dB width equals f₀/Q.
- The generated C code, compiled with a C compiler, gives the same output as SciPy for a cascade of biquads and for an FIR.

### How-to examples

Each example is a complete input; the results are from runs of the Actor (also listed under **Examples**).

#### How to design a Butterworth low-pass filter

```json
{"filters": ["lowpass 100 Hz, fs 1 kHz, 4th order Butterworth"]}
```

Result: -3 dB at 99.94 Hz, the same sections as SciPy's `butter`, a group delay of 4.02-6.53 ms in the passband, and stable. You get the second-order sections, a frequency response chart and ready-to-paste C, Python and MATLAB code.

#### How to find the filter order that meets a spec

```json
{"filters": ["lowpass 100 Hz, fs 1 kHz, 0.5 dB ripple, 40 dB down at 200 Hz", "FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple"]}
```

Result: an order 8 Butterworth with 0.498 dB ripple and 46.8 dB at 200 Hz; and a 111-tap equiripple FIR (109 taps fall short) with 0.472 dB ripple, 60.7 dB stopband and 55 samples (1.15 ms) of delay.

#### How to design a notch filter for 50 or 60 Hz hum

```json
{"filters": ["notch 50 Hz, Q 20, fs 1 kHz"]}
```

Result: a full null at 50 Hz, with -3 dB points at 48.76 and 51.27 Hz.

#### How to let an AI agent design filters

Add this Actor to the [Apify MCP server](https://mcp.apify.com) with `https://mcp.apify.com/?tools=jumblemog/digital-filter-designer`. The agent describes the filter in one line and gives the user measured coefficients and code that was compiled and tested, instead of writing filter math from memory.

### FAQ

**Which filter types are there?** IIR Butterworth, Chebyshev I and II, elliptic and Bessel, FIR by window (Kaiser and others) and equiripple, and notch and peak filters, as low-pass, high-pass, band-pass and band-stop.

**Can I get C code for a microcontroller?** Yes: a biquad cascade or an FIR with a circular buffer. The tests compile it and check its output against SciPy.

**Does it check fixed-point coefficients?** Yes. Set `coefficientBits` (4 to 32) and it gives the Q format and integers, and says whether the filter still works.

**Can it filter my data?** Yes. Pass a signal and get it back filtered, causally or with zero phase.

**Does it work with Zapier, Make or n8n?** Yes. Call the Actor with its Apify app or an HTTP request and pass the coefficients on.

### Input

| Field | What it is |
|---|---|
| `filters` | Filters, as text lines or objects (see below). |
| `sampleRate` | Default sample rate in Hz, for filters that don't give one. |
| `coefficientBits` | Round every filter to this many bits and check it. |
| `charts` | Draw charts (default on). |

**A filter as an object** takes:

- `band`, `sampleRate`, and `cutoff` (one frequency, or two for band filters).
- `type` (`iir` or `fir`), `family` (`butterworth`, `chebyshev1`, `chebyshev2`, `elliptic`, `bessel`), `method` (`window`, `kaiser`, `equiripple`, `least-squares`) and `window`.
- `order` or `taps`.
- `ripple` and `attenuation` in dB, and `stopband` (edge frequencies) or `transition` (width).
- `q` or `bandwidth`, for notch and peak filters.
- `coefficientBits`, `signal`, `zeroPhase` and `title`.
- `text`: a line of text to start from, which the other fields override.

Frequencies can be numbers in Hz or text like `"1.5 kHz"`.

### Output

One dataset item per filter, also saved together in the run's `OUTPUT` record:

```json
{
  "request": 1,
  "status": "ok",
  "title": "4th-order Butterworth lowpass at 100 Hz",
  "summary": "4th-order Butterworth lowpass at 100 Hz (fs 1 kHz): -3 dB at 99.94 Hz, group delay 4.02-6.53 ms in the passband, stable.",
  "band": "lowpass", "filterType": "iir", "design": "Butterworth, order 4", "sampleRate": 1000, "cutoff": [100], "order": 4,
  "coefficients": {
    "sos": [[0.0048243433577162282, 0.0096486867154324564, 0.0048243433577162282, 1, -1.0485995763626117, 0.29614035756166962],
            [1, 2, 1, 1, -1.3209134308194264, 0.63273879288527657]],
    "b": ["..."], "a": ["..."], "zeros": ["..."], "poles": [{"real": 0.6605, "imag": 0.4433, "radius": 0.7954}, "..."], "gain": 0.00482
  },
  "response": {"gainAtCutoffDb": [-3.0103], "minus3dB": [99.9445], "passbandRippleDb": null, "stopbandAttenuationDb": null,
               "groupDelayMs": {"min": 4.02, "max": 6.53}, "linearPhase": false, "stable": true, "poleRadius": 0.795,
               "points": [{"f": 0, "db": 0}, "..."]},
  "impulseResponse": [0.00482, 0.0307, 0.0906, "..."],
  "code": {"c": "/* Butterworth, order 4 ... */ ...", "python": "...", "matlab": "..."},
  "imageUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-....png",
  "markdownUrl": "https://api.apify.com/v2/key-value-stores/.../records/001-....md"
}
```

Some results add more:

- **With `coefficientBits`**: `quantized` holds `format`, `scale`, `integers`, `stable`, `maxPassbandChangeDb` and `stopbandAttenuationDb`.
- **With `signal`**: `filtered` holds `output` and `csvUrl`.
- **Every result** has `warnings` (instability, poles very close to the unit circle, specs not met, fixed-point damage) and `notes` (the order found, defaults used).

A filter that can't be designed has `"status": "failed"` and the reason in `error`, and isn't billed.

### How it works

1. The text is split into its parts: frequencies by their units, the sample rate by its label, and orders, taps, dB levels and family names by their words.
2. IIR filters are designed in second-order sections with SciPy (`butter`, `cheby1`, `cheby2`, `ellip`, `bessel`). The order comes from `buttord`, `cheb1ord`, `cheb2ord` or `ellipord`. Notches and peaks come from `iirnotch` and `iirpeak`.
3. FIR filters come from `firwin` (with `kaiserord` for Kaiser), `remez` or `firls`. Equiripple weights come from the ripple and the attenuation.
4. Every filter is then measured on an 8,192-point grid, with the exact gain at the cutoff. Group delay is added up section by section.
5. Charts are drawn with Vega-Lite and rendered with vl-convert.

### Pricing

You pay one low price per filter designed, at the price shown on this page. It includes the code, the chart, the report, the fixed-point check and the filtered signal. Filters that can't be designed are never charged. If you set a maximum cost per run, the Actor stops before a filter that wouldn't fit.

### Speed

A filter takes a few hundredths of a second plus its chart. A run through the API answers in about 5 to 10 seconds, including the cloud container starting.

### Tips and limits

- **Use second-order sections** for IIR filters above order 2 or so. The single b/a polynomial loses precision, and the result warns when the poles sit very close to the unit circle. The C code switches to double precision there.
- **Butterworth and Bessel cutoffs** are their -3 dB points. A windowed FIR cutoff is its -6 dB point. Give a stopband edge to design to the passband edge instead.
- **Chebyshev II with an order and no stopband**: the frequency you give is where the stopband begins.
- **Highpass and bandstop FIRs** need an odd number of taps; an even count is raised by one.
- **Limits**: IIR order up to 40, FIR up to 20,001 taps (8,001 when the length is found for you), 500 filters per run, signals up to 1,000,000 samples.

### For AI agents and developers

This Actor works with the [Apify MCP server](https://mcp.apify.com), so AI agents can call it as a tool. Pass `filters` as plain text and read `summary`, `coefficients.sos` (or `coefficients.b`) and `code` from the result. A direct API call that waits for the answer:

```bash
curl -X POST "https://api.apify.com/v2/acts/jumblemog~digital-filter-designer/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filters": ["highpass 0.5 Hz, fs 250 Hz, 2nd order Butterworth", "notch 60 Hz, Q 30, fs 250 Hz"]}'
```

`run-sync` instead returns the run's `OUTPUT`: the status, the counts and every result as JSON.

In Python, with the `apify-client` package:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("jumblemog/digital-filter-designer").call(run_input={
    "filters": [{"band": "bandpass", "cutoff": ["0.5 Hz", "40 Hz"], "sampleRate": 500, "family": "butterworth",
                 "order": 4, "coefficientBits": 16}],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["summary"])
    print(item["code"]["c"])
```

### Credits

- Filter design and analysis: [SciPy](https://scipy.org) `scipy.signal` (BSD-3-Clause).
- Charts: [Vega-Lite](https://vega.github.io/vega-lite/) and [vl-convert](https://github.com/vega/vl-convert) (BSD-3-Clause), with the [Inter](https://rsms.me/inter/) font (SIL Open Font License).
- Methods:
  - McClellan, J. H., Parks, T. W. and Rabiner, L. R. (1973), *A computer program for designing optimum FIR linear phase digital filters*, IEEE Trans. Audio Electroacoustics 21(6), 506-526.
  - Kaiser, J. F. (1974), *Nonrecursive digital filter design using the I₀-sinh window function*, Proc. IEEE ISCAS.
  - Oppenheim, A. V. and Schafer, R. W., *Discrete-Time Signal Processing*, 3rd ed., Pearson.

# Actor input Schema

## `filters` (type: `array`):

One filter per entry, as text or an object. Text: 'lowpass 100 Hz, fs 1 kHz, 4th order Butterworth', 'highpass 0.5 Hz, fs 250 Hz, 2nd order', 'bandpass 300-3400 Hz, fs 8 kHz, 1 dB ripple, 40 dB down at 200 Hz and 3.8 kHz, elliptic', 'FIR lowpass 5 kHz, fs 48 kHz, 101 taps, Hamming', 'FIR lowpass 5 kHz, fs 48 kHz, 60 dB down at 6 kHz, equiripple', 'notch 60 Hz, Q 30, fs 1 kHz'. Object fields: band (lowpass, highpass, bandpass, bandstop, notch, peak), sampleRate, cutoff (a frequency, or two for band filters), type (iir or fir), family (butterworth, chebyshev1, chebyshev2, elliptic, bessel), method (window, kaiser, equiripple, least-squares), window (hamming, hann, blackman, ...), order or taps, ripple (dB), attenuation (dB), stopband (edge frequencies) or transition (width), q or bandwidth (notch/peak), zeroPhase, coefficientBits (round to fixed point and check), signal (numbers to run through the filter), title, and text (a line of text to start from). Without an order or taps, the shortest filter that meets the ripple and attenuation at the stopband edge is found.

## `sampleRate` (type: `number`):

Used for filters that don't give their own sample rate.

## `coefficientBits` (type: `integer`):

Round every filter's coefficients to this many bits (such as 16) and check the response and stability that result. Leave empty for floating point.

## `charts` (type: `boolean`):

Draw the magnitude response, group delay, impulse response and pole-zero plot for each filter (PNG and SVG).

## Actor input object example

```json
{
  "filters": [
    "lowpass 100 Hz, fs 1 kHz, 4th order Butterworth",
    {
      "title": "Telephone voice band",
      "text": "bandpass 300-3400 Hz, fs 8 kHz, 1 dB ripple, 40 dB down at 200 Hz and 3.8 kHz, elliptic",
      "coefficientBits": 16
    },
    "FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple",
    {
      "title": "Mains hum remover",
      "text": "notch 50 Hz, Q 20, fs 1 kHz"
    }
  ],
  "charts": true
}
```

# Actor output Schema

## `results` (type: `string`):

One row per filter: the summary and chart.

## `output` (type: `string`):

The OUTPUT record: every result in one JSON object.

## `files` (type: `string`):

Charts (PNG and SVG), Markdown reports and filtered-signal CSV files in the run's key-value store.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "filters": [
        "lowpass 100 Hz, fs 1 kHz, 4th order Butterworth",
        {
            "title": "Telephone voice band",
            "text": "bandpass 300-3400 Hz, fs 8 kHz, 1 dB ripple, 40 dB down at 200 Hz and 3.8 kHz, elliptic",
            "coefficientBits": 16
        },
        "FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple",
        {
            "title": "Mains hum remover",
            "text": "notch 50 Hz, Q 20, fs 1 kHz"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jumblemog/digital-filter-designer").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "filters": [
        "lowpass 100 Hz, fs 1 kHz, 4th order Butterworth",
        {
            "title": "Telephone voice band",
            "text": "bandpass 300-3400 Hz, fs 8 kHz, 1 dB ripple, 40 dB down at 200 Hz and 3.8 kHz, elliptic",
            "coefficientBits": 16,
        },
        "FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple",
        {
            "title": "Mains hum remover",
            "text": "notch 50 Hz, Q 20, fs 1 kHz",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("jumblemog/digital-filter-designer").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "filters": [
    "lowpass 100 Hz, fs 1 kHz, 4th order Butterworth",
    {
      "title": "Telephone voice band",
      "text": "bandpass 300-3400 Hz, fs 8 kHz, 1 dB ripple, 40 dB down at 200 Hz and 3.8 kHz, elliptic",
      "coefficientBits": 16
    },
    "FIR lowpass 5 kHz, fs 48 kHz, 0.5 dB ripple, 60 dB down at 6 kHz, equiripple",
    {
      "title": "Mains hum remover",
      "text": "notch 50 Hz, Q 20, fs 1 kHz"
    }
  ]
}' |
apify call jumblemog/digital-filter-designer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jumblemog/digital-filter-designer"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cUXNz2gkPXPExahuP/builds/P0JdWq94GgTpupHzZ/openapi.json
