Zapier Integration
Connect Brainpercent to 6,000+ apps using Zapier's "Webhooks by Zapier" action with exact field-by-field configuration.
Overview
Zapier doesn't have a native Brainpercent app yet. Instead, use the "Webhooks by Zapier" premium action to call any Brainpercent API endpoint directly. This guide shows the exact settings for every field in Zapier's interface.
Zapier plan required: "Webhooks by Zapier" is a premium app. Multi-step Zaps with Delay and Paths also require a paid plan (Starter or higher).
Prerequisites
- A Zapier account on a paid plan (Starter, Professional, or Team)
- A Brainpercent API key with
readandwritepermissions - Your API key starts with
bp_. Create one at brainpercent.app/chat/developers. Keys cannot be created over the API, so this is a one-time manual step. - A project id. Every generation call needs one. Grab it once with
GET https://www.brainpercent.app/api/v1/projectsand paste it into your Zap, or add that call as a step. Projects are created in the app, not over the API.
Use the www host in every URL. The apex https://brainpercent.app answers with a 307 redirect and the POST body is dropped when Zapier follows it, so the request arrives empty and fails validation.
Setting Up "Webhooks by Zapier"
Step 1: Add the Action
In your Zap editor, click the + button to add an action step. Search for "Webhooks by Zapier" and select it. Choose "Custom Request" as the Action Event, not "POST" or "GET": Custom Request gives you full control over all fields.
Step 2: Configure Every Field
Here are the exact values for each field in the Custom Request configuration panel:
| Zapier Field | Value to Enter |
|---|---|
| Method | POST |
| URL | https://www.brainpercent.app/api/v1/articles/generate |
| Data Pass-Through? | No (we send a custom JSON body) |
| Data | The raw JSON body (see below) |
| Unflatten | No |
| Basic Auth | Leave blank (we use header auth) |
| Headers | Two key-value pairs (see below) |
Step 3: Headers (Key-Value Pairs)
In the Headers section, click "+ Add Header" to add each row:
| Key | Value |
|---|---|
Authorization | Bearer bp_your_api_key_here |
Content-Type | application/json |
Pro tip: Store your API key as a Zapier "Custom Value" or "Secret" so you can reuse it across multiple Zaps without copying it each time.
Step 4: Data (JSON Body)
In the "Data" field, paste this exact JSON. You can use Zapier template variables from previous trigger steps (shown with {{curly braces}}).
{
"topic": "Your Article Topic Here",
"project_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"keywords": ["keyword1", "keyword2"],
"tone": "professional",
"word_count": 1200
}topic (3 to 500 characters) and project_id are required. Optional: keywords (up to 20), tone (professional, casual, academic, conversational), and word_count (300 to 5000, default 800). There is no length field and no language field: the language comes from the project.
Step 5: Test the Action
Click "Test step". Zapier shows the raw API response. You should see:
{
"success": true,
"data": {
"article_id": "a1b2c3d4-e5f6-...",
"status": "queued",
"job_id": "job_01hxyz",
"slug": "your-article-topic-here",
"language": "en",
"credits_deducted": 1,
"credits_remaining": 32,
"estimated_time": "10-15 minutes",
"poll_url": "/api/v1/articles/a1b2c3d4-e5f6-.../status"
}
}Multi-Step Zap: Full Content Pipeline
Generate an article, wait for it to complete, then auto-generate social media content. This requires 5 Zapier steps:
Flow: Trigger → Generate Article → Delay 20 min → Check Status → Generate Social
There are no webhook callbacks, so the Delay step is doing the waiting for you. The status endpoint returns an is_complete boolean: branch on that rather than on a status string, and never wait for published, which is not an article status.
Step 1: Trigger
Choose any trigger: "RSS by Zapier → New Item in Feed", "Schedule by Zapier → Every Day", or "Google Sheets → New Row".
Step 2: Webhooks by Zapier: Generate Article
Configure exactly as shown in the setup section above. Use trigger data for the topic:
{
"topic": "{{1. Title}}",
"project_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"keywords": ["{{1. Category}}"],
"tone": "professional",
"word_count": 900
}Step 3: Delay by Zapier: Wait for Generation
| Zapier Field | Value |
|---|---|
| Action Event | Delay For |
| Time Delayed For (Value) | 20 |
| Time Delayed For (Unit) | minutes |
Article generation takes roughly 10 to 15 minutes, so a 20-minute delay is a safe buffer. Zapier's Delay step pauses the Zap execution and does not count against your task quota. If the status check still comes back incomplete, add a second Delay plus a repeat check.
Step 4: Webhooks by Zapier: Check Article Status
| Field | Value |
|---|---|
| Method | GET |
| URL | https://www.brainpercent.app/api/v1/articles/{{2. data__article_id}}/status |
| Headers | Same Authorization header as Step 2 |
Note: Zapier flattens nested JSON keys with double underscores. The data.article_id from Step 2 becomes {{2. data__article_id}} in the Zapier variable picker.
This step returns data.is_complete, data.status, data.progress, data.title, and data.slug. Use {{4. data__is_complete}} in a Filter or Path so the Zap only continues when the article is actually done.
Step 5: Webhooks by Zapier: Generate Social Content
| Field | Value |
|---|---|
| Method | POST |
| URL | https://www.brainpercent.app/api/v1/social/generate |
| Headers | Same as Step 2 |
{
"source_url": "https://www.brainpercent.app/articles/{{4. data__slug}}",
"platforms": ["twitter", "linkedin"],
"project_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"angle": "Practical takeaways for busy marketers"
}source_url and platforms (1 to 10) are required. Optional: source_type (website, blog, youtube), angle, title, and project_id. There is no tone or language field: use angle to steer the direction. Valid platforms: instagram, facebook, linkedin, twitter, threads, tiktok, bluesky, pinterest, google_business, telegram. Costs 0.6 credits per platform, and the response holds one data.content_id covering all of them.
Optional Step 6: Publish or Schedule
Add another Custom Request to POST https://www.brainpercent.app/api/v1/social/publish. Wait until the content is ready first (a Delay plus a GET on /social/content/{id}), otherwise the call returns 412.
{
"content_id": "{{5. data__content_id}}"
}Only content_id is required. platforms is an optional subset: omit it to publish every variant. With no scheduled_at the API returns 202 and publishes immediately; with one it returns 200 and schedules. A 412 also means the account has no connected social profiles.
Parsing Responses with "Code by Zapier"
While Zapier auto-parses JSON from the Webhooks step, sometimes you need to transform data. Add a "Code by Zapier" step (JavaScript) after your webhook to extract specific fields:
Code Step Configuration
| Zapier Field | Value |
|---|---|
| Action Event | Run Javascript |
| Input Data: Key | rawResponse |
| Input Data: Value | Map the full response body from the Webhooks step |
// Code by Zapier: Run Javascript
// inputData.rawResponse contains the API response
const response = JSON.parse(inputData.rawResponse);
if (response.success) {
output = [{
articleId: response.data.article_id || response.data.id,
status: response.data.status, // 'queued' on create, 'cms' when done
isComplete: response.data.is_complete === true,
slug: response.data.slug || '',
creditsUsed: response.data.credits_deducted || 0,
creditsLeft: response.data.credits_remaining,
}];
} else {
output = [{
error: response.error?.code || 'UNKNOWN',
message: response.error?.message || 'Request failed',
}];
}Error Handling with Zapier Paths
Use Paths by Zapier (conditional logic) after the Webhooks step to handle success and failure:
Path Configuration
| Path | Rule | Action |
|---|---|---|
| Path A: Accepted | {{Webhook. success}} (Text) Exactly matches true | Continue to next step (Delay, status check, etc.) |
| Path B: Failure | {{Webhook. success}} (Text) Does not exactly match true | Send Slack/Email notification with error details |
Handling Rate Limits (429)
In the Custom Request settings, check the "Continue On Error" checkbox (under "Show Advanced Options"). This prevents the Zap from halting on 429 responses. Then use a Path step to check the HTTP status code and add a Delay before retrying. Free keys get 100 requests per minute and 5,000 per day; paid plans get 1,000 per minute and 50,000 per day.
Other Codes Worth Branching On
402 INSUFFICIENT_CREDITS: do not retry. Alert yourself and top up.400 NO_PROJECT: theproject_idis missing or the account has no projects.412 PRECONDITION_FAILEDon publish: the content is still generating, or no social accounts are connected. Add a Delay and retry.
Example Zaps
RSS Feed → Article Generation
Trigger: RSS by Zapier → New Item in Feed
Action: Webhooks by Zapier → Custom Request (POST /articles/generate)
Delay: Delay by Zapier → 20 minutes
Status: Webhooks by Zapier → Custom Request (GET /articles/:id/status)
Social: Webhooks by Zapier → Custom Request (POST /social/generate)
Google Sheets → Bulk Article Generation
Trigger: Google Sheets → New Spreadsheet Row
Action: Webhooks by Zapier → Custom Request with sheet columns as variables
{
"topic": "{{1. Column A - Topic}}",
"project_id": "{{1. Column B - Project Id}}",
"keywords": ["{{1. Column C - Keyword 1}}", "{{1. Column D - Keyword 2}}"],
"tone": "{{1. Column E - Tone}}",
"word_count": 1200
}Daily Schedule → Social Content
Trigger: Schedule by Zapier → Every Day at 9:00 AM
Fetch: Webhooks → GET /articles?status=cms&limit=1&sort=created_at&order=desc
Generate: Webhooks → POST /social/generate with article slug from step 2
Tips & Best Practices
- Store your API key as a Zapier "Custom Value" or in Zapier's Secret Manager for reuse across Zaps
- Always use "Custom Request" (not "POST") to get full control over headers and body
- Enable "Continue On Error" in advanced settings to handle 4xx/5xx without halting
- Use "Formatter by Zapier" to split comma-separated keywords into arrays
- Use Paths after webhook steps for success/failure branching
- Monitor credit balance weekly with a scheduled GET /user/credits Zap. It is one balance for everything: an article costs 1.5 credits, social costs 0.6 credits per platform.
- Zapier uses double underscores for nested JSON:
data__article_id - Hard-code the
project_idas a Zapier Custom Value. It rarely changes and it is required on every generate call. - Filter on
data__is_complete, not on a status string. A finished article iscms, neverpublished.