> For the complete documentation index, see [llms.txt](https://docs.pullbay.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pullbay.com/documentation/integrations/pullbay-x-n8n-integration.md).

# Pullbay x n8n Integration

n8n is a powerful open-source and cloud-based workflow automation platform that lets you build complex data pipelines without writing code. This guide shows you how to integrate Pullbay with n8n to automate App Store data collection, monitoring, and analysis workflows.

## What Is n8n?

n8n is a visual workflow automation tool that connects APIs, databases, and applications through a drag-and-drop interface. You can:

* Build complex data pipelines without coding
* Schedule recurring workflows (daily, hourly, weekly, etc.)
* Connect to 400+ apps and services (Google Sheets, Slack, Airtable, etc.)
* Transform and process data between systems
* Trigger workflows based on events or schedules

## Why Use n8n with Pullbay?

### No-Code Integration

Build workflows without any programming knowledge using the visual workflow builder.

### Seamless Integration with Business Tools

Connect Pullbay data directly to:

* **Google Sheets** — automatically populate spreadsheets with review data
* **Slack** — send alerts when low-score reviews appear
* **Airtable** — store structured review data for team collaboration
* **Webhooks** — trigger actions in your own applications
* **Databases** — write data directly to PostgreSQL, MySQL, or other databases

### Bulk Fetch with `maxItems`

Use the `maxItems` parameter to have Pullbay auto-paginate Apple's API internally and return up to 500 reviews in a single response. No pagination loops needed in your workflow.

### Scheduled Execution

Configure workflows to run on a schedule: daily collection at midnight, hourly monitoring for low-score feedback, or weekly competitive analysis reports.

### Error Handling and Reliability

n8n includes built-in error handling, retry logic, and notifications so you know when something goes wrong.

## Setup: Storing Your API Key

Before creating workflows, store your Pullbay API key as a reusable credential in n8n.

{% stepper %}
{% step %}

## Access Credentials

1. Log in to n8n
2. Click **Credentials** in the left sidebar
3. Click **Create New**
   {% endstep %}

{% step %}

## Create Header Authentication Credential

1. Select **Header Auth** from the credential type dropdown
2. Fill in the following:

| Field               | Value                 |
| ------------------- | --------------------- |
| **Credential Name** | `Pullbay API`         |
| **Header Name**     | `Authorization`       |
| **Header Value**    | `Bearer YOUR_API_KEY` |

3. Replace `YOUR_API_KEY` with your actual key from the Pullbay dashboard
4. Click **Create**

Your credential is now stored securely and reusable across all workflows.
{% endstep %}
{% endstepper %}

## HTTP Request Node Configuration

All Pullbay workflows use the **HTTP Request** node with this base configuration:

| Setting              | Value                                              |
| -------------------- | -------------------------------------------------- |
| **Method**           | GET                                                |
| **URL**              | `https://api.pullbay.com/appstore/reviews`         |
| **Authentication**   | Header Auth — select your `Pullbay API` credential |
| **Query Parameters** | See examples below                                 |

### Query Parameters

| Parameter  | Value                     | Notes                                                          |
| ---------- | ------------------------- | -------------------------------------------------------------- |
| `appId`    | Your App Store numeric ID | Required (8–12 digits). Mutually exclusive with `bundleId`.    |
| `bundleId` | Your app bundle ID        | Alternative to `appId`. E.g. `com.burbn.instagram`.            |
| `country`  | 2-letter country code     | Optional. Default: `us`                                        |
| `sort`     | `recent` or `helpful`     | Optional. Default: `recent`                                    |
| `maxItems` | Integer 1–500             | Optional. Omit to fetch one page (\~50 reviews) with a cursor. |
| `page`     | Integer 1–10              | Optional. Mutually exclusive with `maxItems`.                  |

**`maxItems` and `page` cannot be used together.**

## Fetch Mode: `maxItems` vs. `page`

Pullbay has two fetch modes on the same endpoint:

| Mode            | Parameter          | Behavior                                                                                                          | Use in n8n                               |
| --------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| **Bulk**        | `maxItems=500`     | Pullbay auto-paginates Apple's API internally and returns all results in one response. No cursor in the response. | Recommended for most workflows           |
| **Single page** | `page=1` (or omit) | Returns \~50 reviews and a pagination cursor.                                                                     | Use only if you need per-page processing |

For n8n workflows, **always use `maxItems`**. Single-page pagination requires loop logic that is complex to manage in a visual workflow builder.

## Basic Workflow Structure

Every Pullbay workflow in n8n follows this pattern:

```
[Trigger] → [HTTP Request] → [Set: extract data] → [Process/Filter] → [Destination]
```

1. **Trigger** — schedule, webhook, or manual start
2. **HTTP Request** — fetch data from Pullbay (`/api/appstore/reviews`)
3. **Set** — extract `{{ $json.data }}` from the response envelope
4. **Process/Filter** — transform, filter, or split reviews as needed
5. **Destination** — Google Sheets, Slack, Airtable, database, etc.

## Example Workflows

### Workflow 1: Daily Review Collection to Google Sheets

Automatically fetch app reviews every day at 9 AM and save them to Google Sheets.

{% stepper %}
{% step %}

## Schedule Trigger

* Trigger type: Every day
* Time: 9:00 AM
  {% endstep %}

{% step %}

## HTTP Request — fetch reviews

* Method: GET
* URL: `https://api.pullbay.com/appstore/reviews`
* Authentication: Pullbay API (Header Auth)
* Query parameters:
  * `appId`: `284882215`
  * `country`: `us`
  * `sort`: `recent`
  * `maxItems`: `500`
    {% endstep %}

{% step %}

## Set Node — extract reviews array

* Set a field `reviews` to `{{ $json.data }}`
  {% endstep %}

{% step %}

## Split In Batches

* Batch size: 1 (one review per row)
  {% endstep %}

{% step %}

{% endstep %}

{% step %}

## Google Sheets — Append Row

{% endstep %}

{% step %}

* Document: your Google Sheets document
* Sheet: `Reviews`
* Columns mapped from review fields:
  {% endstep %}

{% step %}

## Slack or Email Notification

* Notify when the run completes

**Expected outcome**: Your Google Sheets document is updated every morning with the latest reviews, creating a historical record of app feedback.
{% endstep %}
{% endstepper %}

| Sheet Column | n8n Expression         |
| ------------ | ---------------------- |
| Date         | `{{ $json.date }}`     |
| Score        | `{{ $json.score }}`    |
| Title        | `{{ $json.title }}`    |
| Review       | `{{ $json.text }}`     |
| Author       | `{{ $json.userName }}` |
| Version      | `{{ $json.version }}`  |
| Country      | `{{ $json.country }}`  |
| Review ID    | `{{ $json.id }}`       |
| {% endstep}  |                        |

### Workflow 2: Review Monitoring with Slack Alerts

Hourly monitoring that sends a Slack message for every review with a score ≤ 2.

{% stepper %}
{% step %}

## Schedule Trigger

* Trigger type: Every hour
  {% endstep %}

{% step %}

## HTTP Request — fetch recent reviews

* URL: `https://api.pullbay.com/appstore/reviews`
* Query parameters:
  * `appId`: `284882215`
  * `country`: `us`
  * `sort`: `recent`
  * `maxItems`: `100`
    {% endstep %}

{% step %}

## Set Node

* Set `reviews` to `{{ $json.data }}`
  {% endstep %}

{% step %}

## Split In Batches

* Batch size: 1
  {% endstep %}

{% step %}

## If Node — filter low scores

* Condition: `{{ $json.score }}` ≤ `2`
* True branch: continue to Slack
* False branch: No Operation
  {% endstep %}

{% step %}

## Slack — Send Message

```
🚨 Critical Review Alert
Author: {{ $json.userName }}
Score: {{ $json.score }} / 5
Title: {{ $json.title }}
Review: {{ $json.text }}
Version: {{ $json.version }}
Country: {{ $json.country }}
Date: {{ $json.date }}
```

**Expected outcome**: Your team gets an instant Slack notification for every 1–2 star review, allowing fast responses to critical feedback.
{% endstep %}
{% endstepper %}

### Workflow 3: Competitive Analysis (Multiple Apps, Weekly)

Monitor competitor apps and compile findings into a weekly report.

{% stepper %}
{% step %}

## Schedule Trigger

* Every Monday at 9:00 AM
  {% endstep %}

{% step %}

## Code Node — define apps to monitor

```javascript
return [
  { json: { appId: "284882215", name: "Facebook" } },
  { json: { appId: "389801252", name: "Instagram" } },
  { json: { appId: "310633997", name: "WhatsApp" } },
];
```

{% endstep %}

{% step %}

## HTTP Request — fetch reviews for each app

* URL: `https://api.pullbay.com/appstore/reviews`
* Query parameters:
  * `appId`: `{{ $json.appId }}`
  * `country`: `us`
  * `sort`: `recent`
  * `maxItems`: `100`
    {% endstep %}

{% step %}

## Code Node — build summary

```javascript
const appName = $('Code Node').first().json.name;
const reviews = $json.data;
const scores  = reviews.map(r => r.score);
const avg     = scores.reduce((a, b) => a + b, 0) / scores.length;

return [{
  json: {
    app:           appName,
    totalReviews:  reviews.length,
    averageScore:  avg.toFixed(2),
    lowScoreCount: scores.filter(s => s <= 2).length,
    date:          new Date().toISOString(),
  }
}];
```

{% endstep %}

{% step %}

## Google Sheets — Append Row

* Write summary: date, app name, average score, review count, low-score count
  {% endstep %}

{% step %}

## Slack Notification

* Send weekly summary to your product team

**Expected outcome**: Every Monday, your team receives a competitive intelligence report showing how competitor apps are being reviewed.
{% endstep %}
{% endstepper %}

### Workflow 4: Sentiment Analysis with OpenAI

Fetch reviews and automatically analyze sentiment using OpenAI.

{% stepper %}
{% step %}

## Schedule Trigger

* Every day at midnight
  {% endstep %}

{% step %}

## HTTP Request — fetch recent reviews

* URL: `https://api.pullbay.com/appstore/reviews`
* Query parameters:
  * `appId`: `284882215`
  * `sort`: `recent`
  * `maxItems`: `50`
    {% endstep %}

{% step %}

## Set Node

* Set `reviews` to `{{ $json.data }}`
  {% endstep %}

{% step %}

## Split In Batches

* Batch size: 1
  {% endstep %}

{% step %}

## OpenAI Node — analyze sentiment

```
Analyze the sentiment of this app review. Respond with:
- sentiment: positive, negative, or neutral
- score: -1 to 1
- topics: comma-separated key topics

Review title: {{ $json.title }}
Review text: {{ $json.text }}
Star score: {{ $json.score }}/5
```

{% endstep %}

{% step %}

## Airtable — Store Results

* Review text: `{{ $json.text }}`
* Star score: `{{ $json.score }}`
* AI sentiment: from OpenAI response
* AI score: from OpenAI response
* Topics: from OpenAI response
* Analyzed at: `{{ new Date().toISOString() }}`
  {% endstep %}

{% step %}

## Notification

* Alert when negative sentiment exceeds a threshold

**Expected outcome**: A database of reviews with AI-powered sentiment analysis, identifying trends and emotional patterns in customer feedback.
{% endstep %}
{% endstepper %}

## Handling Response Data in n8n

The Pullbay API always returns the same envelope. In the Set node, extract the reviews array:

```
{{ $json.data }}
```

Log credit usage and request ID after each call:

```
Credits charged: {{ $json.pricing.creditsCharged }}
Request ID:      {{ $json.requestId }}
```

### Individual Review Field Reference

After **Split In Batches** (batch size 1), each item is a single review. Reference fields as:

| Field       | n8n Expression         | Description                 |
| ----------- | ---------------------- | --------------------------- |
| Review ID   | `{{ $json.id }}`       | Unique review identifier    |
| Date        | `{{ $json.date }}`     | ISO 8601 datetime           |
| Score       | `{{ $json.score }}`    | Integer 1–5                 |
| Title       | `{{ $json.title }}`    | Review headline             |
| Review text | `{{ $json.text }}`     | Full review body            |
| Author      | `{{ $json.userName }}` | Reviewer display name       |
| App version | `{{ $json.version }}`  | App version reviewed        |
| Country     | `{{ $json.country }}`  | 2-letter country code       |
| Review URL  | `{{ $json.url }}`      | Link to the review on Apple |

## Error Handling

### Configure Timeout

In the HTTP Request node, click **Additional options** and set **Timeout** to `120000` ms (2 minutes). This gives the bulk fetch endpoint enough time to retrieve all pages internally when `maxItems` is large.

### Enable Retry Logic

{% stepper %}
{% step %}

## Enable Retry Logic

1. In the HTTP Request node settings, enable **Retry On Fail**
2. Set retry attempts to **3**
3. Enable **Continue On Fail** if you want the workflow to keep running even when one request fails
   {% endstep %}

{% step %}

## Add an Error Path

1. Connect an error handler path from the HTTP Request node
2. Send a Slack or email notification when the API call fails

Example Slack error message:

```
⚠️ Pullbay API Error
Status:    {{ $json.statusCode }}
Message:   {{ $json.message }}
requestId: {{ $json.requestId }}
Time:      {{ new Date().toISOString() }}
```

{% endstep %}
{% endstepper %}

## Tips and Best Practices

### Test with Small `maxItems` First

When building a workflow, test with a small value to iterate quickly:

```
maxItems=10
```

Once the workflow is working correctly, increase `maxItems` up to 500.

### Track Credit Usage

Log `{{ $json.pricing.creditsCharged }}` after each HTTP Request node so you can monitor credit consumption over time. You can write this value to a dedicated "Credits" sheet in Google Sheets.

### Deduplicate Reviews

If running workflows frequently, track processed review IDs to avoid duplicates:

1. Store `{{ $json.id }}` values in a database or Google Sheet after each run
2. In the If node, skip reviews whose ID already exists in your log
3. Alternatively, filter by `{{ $json.date }}` to process only reviews newer than your last run

### Split Large Datasets

After the Set node, add a **Split In Batches** node before any per-review processing:

* Batch size **1** for per-review actions (Slack message, OpenAI call, etc.)
* Batch size **50–100** for bulk writes (Google Sheets append rows)

Splitting prevents memory issues and enables per-batch error handling.

### Schedule During Off-Peak Hours

For large `maxItems` values, schedule workflows during off-peak hours (typically 10 PM – 6 AM local time) for best performance.

## FAQ

<details>

<summary>Why should I use `maxItems` instead of `page` in n8n?</summary>

With `maxItems`, Pullbay paginates Apple's API internally and returns all results in a single HTTP response. With `page`, you get one page (\~50 reviews) and must build a loop with cursor tracking — complex in a no-code workflow builder. Use `maxItems` for simplicity; use `page` only if you need per-page processing control.

</details>

<details>

<summary>How do I set the timeout for bulk requests?</summary>

In the HTTP Request node, click **Additional options** and set **Timeout** to `120000` ms. This gives the endpoint 2 minutes to fetch all pages internally before returning.

</details>

<details>

<summary>Can I process individual reviews in n8n?</summary>

Yes. After the Set node, add a **Split In Batches** node with batch size 1. Each execution of the next node then receives a single review object.

</details>

<details>

<summary>What if a workflow fails?</summary>

Check the execution history in n8n. Common causes:

* Invalid `appId` — confirm the numeric ID is correct (8–12 digits)
* `429 Too Many Requests` — add retry logic with backoff
* Timeout — increase the timeout or reduce `maxItems`
* `401 Unauthorized` — verify the API key in your credential

</details>

<details>

<summary>Can I test my workflow without consuming credits?</summary>

Every real API call consumes credits. To minimise cost during development, test with `maxItems=5` to fetch only 5 reviews and confirm the workflow structure is correct before scaling up.

</details>

<details>

<summary>Can I run the same workflow for multiple apps?</summary>

Yes. Use a **Code** node to emit one item per app ID, then connect it to the HTTP Request node. n8n runs the HTTP Request for each item, so each app is fetched in sequence. See Workflow 3 above for the pattern.

</details>

## Troubleshooting

**`401 Unauthorized`**

Your API key is invalid or missing from the credential. Re-check the Header Auth credential: Header Name must be `Authorization`, Header Value must be `Bearer <your_key>` (with the word "Bearer" and a space before the key).

**`400 Bad Request`**

A query parameter is invalid. Common mistakes:

* Passing both `maxItems` and `page` in the same request — use only one
* Passing both `appId` and `bundleId` — use only one
* Invalid `sort` value — only `recent` and `helpful` are accepted
* `appId` contains non-numeric characters or is outside 8–12 digits

**`402 Insufficient Credits`**

Your account has run out of credits. Add credits from the Pullbay dashboard before re-running the workflow.

**`404 Not Found`**

Wrong URL. The correct endpoint is exactly:

```
https://api.pullbay.com/appstore/reviews
```

**Workflow runs but no data appears in the destination**

* Verify the Set node expression is `{{ $json.data }}` (not `$json.reviews` or similar)
* Check that the app has reviews in the requested country
* Look at the HTTP Request output panel in the n8n execution view to confirm what the API returned

**Workflow times out**

* Increase the HTTP Request timeout to `120000` ms
* Reduce `maxItems` (e.g. `100` instead of `500`) so there are fewer internal pages to fetch
* Ensure you are not running several large workflows concurrently on the same API key

## Next Steps

1. Store your Pullbay API key as a Header Auth credential in n8n
2. Build and test a simple HTTP Request node with `appId` and `maxItems=10`
3. Add a Set node to extract `{{ $json.data }}` and a Split In Batches node (batch size 1)
4. Connect to your destination (Google Sheets, Slack, Airtable)
5. Set a time-based trigger and monitor the first scheduled run
6. Scale up `maxItems` once the workflow is validated end-to-end

For n8n support, visit [docs.n8n.io](https://docs.n8n.io/). For Pullbay-specific questions, contact support through your dashboard.
