Customer Engagement Platform for Email, Push Notifications, & SMS
모바일 푸시, 웹 푸시, SMS, 이메일, 인앱 메시징 분야 세계 최고, 200만 기업이 신뢰해 연간 120억 건 이상 전송
웹사이트에 입력하면 Balzac이 승리 가능한 검색어를 찾아 기사 작성·ChatGPT 인용·자동 게시합니다
Type your website. Balzac finds the searches you can win, writes articles built to rank on Google and get cited by ChatGPT, and publishes them to your site. On autopilot.
마케팅TypeScriptGitHub @hirebalzac온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Balzac is an AI-powered SEO and GEO content engine, shipped as a CLI, MCP server, and API. The perfect skill for Claude Code, Cursor, OpenClaw, or any AI agent to research keywords, write optimized articles, and publish them to your CMS.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
AI content platform CLI: manage workspaces, keywords, suggestions, articles, and more from the command line.
Built for AI coding agents (Claude Code, Claude Cowork, Codex, Mistral Vibe, Cursor, Windsurf, Cline, Aider) and developers alike, the Balzac CLI provides a complete interface to the Balzac API, enabling automated content creation, SEO keyword management, and article publishing across integrations.
No signup needed for the free SEO tools, such as the AI crawler checker.
Install the Balzac skill for your AI agent (Cursor, Claude Code, OpenClaw, etc.):README 전문 보기 ↗AI content platform CLI: manage workspaces, keywords, suggestions, articles, and more from the command line.
Built for AI coding agents (Claude Code, Claude Cowork, Codex, Mistral Vibe, Cursor, Windsurf, Cline, Aider) and developers alike, the Balzac CLI provides a complete interface to the Balzac API, enabling automated content creation, SEO keyword management, and article publishing across integrations.
No signup needed for the free SEO tools, such as the AI crawler checker.
npm install -g balzac-cli
balzac --version
Install the Balzac skill for your AI agent (Cursor, Claude Code, OpenClaw, etc.):
npx skills add hirebalzac/cli
This installs the SKILL.md which gives your agent full knowledge of the CLI commands, patterns, and workflows.
Required: Set your Balzac API key. You can get your API key by signing up at https://hirebalzac.ai/start/.
# Interactive login (stores key locally)
balzac auth login
# Or set via environment variable
export BALZAC_API_KEY=bz_your_api_key_here
Optional: Set a default workspace so you don't need --workspace on every command
balzac config set workspace <workspace-id>
Optional: Custom API endpoint
export BALZAC_API_URL=https://custom-api.example.com/v1
# Store your API key
balzac auth login
balzac auth login bz_abc123...
# Remove stored key
balzac auth logout
# Check authentication status: account, credits, key name, role and admin flag
balzac auth status
# List all workspaces
balzac workspaces list
balzac workspaces list --status ready
# Create workspace from domain (auto-setup)
balzac workspaces create --domain https://myblog.com
balzac workspaces create --domain https://myblog.com --auto-accept-suggestions --language fr
# Create and wait for setup to complete
balzac workspaces create --domain https://myblog.com --wait
# Get workspace details
balzac workspaces get <workspace-id>
# Update workspace
balzac workspaces update <workspace-id> --name "My Blog" --language en
balzac workspaces update <workspace-id> --target-audience "Founders of small SaaS companies"
# Delete workspace
balzac workspaces delete <workspace-id>
# List keywords
balzac keywords list -w <workspace-id>
balzac keywords list --status enabled
# Create a keyword
balzac keywords create --name "content marketing" -w <workspace-id>
# Get keyword details
balzac keywords get <keyword-id>
# Enable / disable
balzac keywords enable <keyword-id>
balzac keywords disable <keyword-id>
# Generate new keywords with AI (async)
balzac keywords generate
# Delete keyword
balzac keywords delete <keyword-id>
AI-generated content proposals. Accept to start writing, reject to dismiss.
# List suggestions
balzac suggestions list -w <workspace-id>
balzac suggestions list --status proposed
# Get suggestion details
balzac suggestions get <suggestion-id>
# Generate new suggestions (costs 1 credit)
balzac suggestions generate
# Accept a suggestion (starts article writing, costs 5 credits)
balzac suggestions accept <suggestion-id>
# Reject a suggestion
balzac suggestions reject <suggestion-id>
Direct write instructions. Creating a briefing immediately starts the article writing pipeline.
# List briefings
balzac briefings list
# Create a briefing (starts writing, costs 5 credits)
balzac briefings create --topic "How to use AI for content marketing in 2026"
balzac briefings create --topic "SEO tips" --type listicle --length long
# Get briefing details
balzac briefings get <briefing-id>
# Delete briefing
balzac briefings delete <briefing-id>
# List articles (with their live URL once published)
balzac articles list
balzac articles list --status done --published false
# Get article: details, live URL and publications (--json includes the HTML content when done)
balzac articles get <article-id>
# Update article metadata
balzac articles update <article-id> --title "New Title" --slug "new-slug"
# Rewrite article (free, 2 per article)
balzac articles rewrite <article-id>
balzac articles rewrite <article-id> --length long --instructions "More technical depth"
# Regenerate article picture (free, 2 per article; articles get shows New Covers Left)
balzac articles regenerate-picture <article-id>
balzac articles regenerate-picture <article-id> --style watercolor --instructions "Dark background"
# No AI image: the title on a brand color gradient, or a stock photo with no AI fallback
# (422 no_stock_photo when none matches: try other search words with --instructions)
balzac articles regenerate-picture <article-id> --mode title --no-ai-images
balzac articles regenerate-picture <article-id> --mode stock --no-ai-images --instructions "laptop on a desk"
# Publish now: prints the new publication (-q prints only its ID). An article
# already on that integration gets no new publication: the command prints the
# API's message instead, which says when nothing was sent, and --json adds it
# as publish ({"result": "already_published", "publication_id", "message"})
balzac articles publish <article-id> --integration <integration-id>
# Schedule publication: prints the publication ID that cancel-schedule needs
balzac articles schedule <article-id> --integration <id> --at "2026-04-01T10:00:00Z"
# Cancel scheduled publication (articles get lists the publication IDs)
balzac articles cancel-schedule <article-id> --publication <publication-id>
# Export content
balzac articles export <article-id> --format markdown
balzac articles export <article-id> --format html --output article.html
Publishing runs in the background. articles get shows Published: true once the platform accepts the post, and the live URL once the platform reports where it went live. Drafts (Webflow or GoHighLevel set to draft) and webhooks that don't answer with a URL never report one. A send that failed isn't reported, so stop checking after a while: if nothing changes, check the integration's status with balzac integrations get <integration-id>.
A convenience command that creates a briefing and optionally waits for the article to complete.
# Start writing an article
balzac write "How to use AI for marketing"
# Start writing and wait until done
balzac write "SEO tips for 2026" --wait
# With options
balzac write "AI tools comparison" --type listicle --length long --wait
# List competitors
balzac competitors list
# Add a competitor
balzac competitors add --name "Acme Corp" --domain https://acme.com
# Get competitor details
balzac competitors get <competitor-id>
# Remove competitor
balzac competitors remove <competitor-id>
# List reference links
balzac links list
# Add a link
balzac links add --url https://myblog.com/about
# Get link details
balzac links get <link-id>
# Remove link
balzac links remove <link-id>
# List integrations
balzac integrations list
# Create a WordPress integration
balzac integrations create --service wordpress --name "My Blog" \
--wordpress-url https://myblog.com --wordpress-username admin \
--wordpress-password "app_pass_here" --auto-publish
# Discover Webflow resources before creating integration
balzac integrations lookup webflow-sites --token "wf_token"
balzac integrations lookup webflow-collections --token "wf_token" --site-id "site_123"
# Create Webhook integration (auto-publish sends articles automatically, and their
# updates as article.updated; --no-webhook-updates if your endpoint can't update a post)
balzac integrations create --service webhook --name "My Webhook" \
--webhook-url https://example.com/hook \
--webhook-token "optional_bearer_secret" \
--auto-publish
# Turn article.updated on for a webhook connected before updates existed
# (--webhook-updates and --auto-publish take true or false, nothing else)
balzac integrations update <id> --webhook-updates true
# Update an integration. Pointing it to another WordPress site needs the
# application password again in the same command, and a new webhook URL needs
# its bearer token again (when the integration has one).
balzac integrations update <id> --wordpress-url https://newblog.com \
--wordpress-password "app_pass_here"
balzac integrations update <id> --webhook-url https://example.com/new-hook \
--webhook-token "optional_bearer_secret"
# Reconnect / test connection
balzac integrations reconnect <id>
# Get integration details (credentials are never returned)
balzac integrations get <id>
# Delete integration
balzac integrations delete <id>
Balzac sends a POST request to your URL, exactly as written (query string included), with the article as JSON. event is article.published when an article is published there (create the post), and article.updated when an article already published there changed (update the post it created, never create a second one):
{
"event": "article.published",
"article_id": "3f6c1d2e-8a4b-4c5d-9e7f-1a2b3c4d5e6f",
"title": "Article Title",
"content": "Full HTML content of the article",
"slug": "article-slug",
"description": "Short description or excerpt",
"cover_image": "URL to the article's main image",
"published_at": "2026-03-19T15:30:45Z",
"seo_title": "Article Title",
"seo_description": "Short description or excerpt",
"schema_json_ld": "{\"@context\":\"https://schema.org\",\"@graph\":[...]}"
}
article_id is the same on every call for an article: key your posts on it. seo_title and seo_description are plain text for your <title> and meta description, and schema_json_ld is a schema.org JSON-LD string for a script tag of type application/ld+json. An article.updated call carries the whole article again, with the first send's published_at, an updated_at, and external_id when your endpoint answered the first call with an id.
If you provided a webhook_bearer_token, it is included as:
Authorization: Bearer your_token_here
Your endpoint should respond with 200 OK. Set auto_publish to true to receive articles automatically as they are completed (and their updates a few minutes after each edit), or publish manually with balzac articles publish <id> --integration <id>. Publishing an article that is already there updates the post when the article changed, instead of creating another (an article sent to a webhook before updates existed, whose endpoint answered without an id, can still be sent again as article.published). Updates only go to webhooks with updates on: on for new webhooks, off for webhooks connected before updates existed (balzac integrations update <id> --webhook-updates true).
To report where the post went live, answer with a JSON object such as {"id": "1042", "url": "https://example.com/blog/article-slug"}. Balzac saves the URL as the article's live URL, shown by balzac articles get and balzac articles list, and sends the id back with updates. It also accepts link, permalink and a few other keys (see the webhook docs).
# View workspace settings
balzac settings get
# Update settings
balzac settings update --language en --article-length long
balzac settings update --auto-accept-suggestions
balzac settings update --pictures-style watercolor --period week --max-articles 10
# List available tones
balzac tones list
# Get tone details
balzac tones get <tone-id>
# Set default workspace
balzac config set workspace <workspace-id>
# Set API key
balzac config set api-key bz_abc123...
# View all config
balzac config get
# View specific value
balzac config get workspace
# Reset config
balzac config reset
Default: Human-friendly colored output with tables
balzac workspaces list
JSON mode: Raw JSON for scripting and piping
balzac --json workspaces list
balzac --json articles get <id> | jq '.title'
Quiet mode: IDs only
balzac -q workspaces list
#!/bin/bash
# 1. Create workspace from domain and wait for setup
balzac workspaces create --domain https://myblog.com --wait
# 2. Set it as default
WORKSPACE_ID=$(balzac --json workspaces list | jq -r '.[0].id')
balzac config set workspace "$WORKSPACE_ID"
# 3. Generate suggestions
balzac suggestions generate
# Wait a moment for suggestions to appear
sleep 30
# 4. Accept the first proposed suggestion
SUGGESTION_ID=$(balzac --json suggestions list --status proposed | jq -r '.[0].id')
balzac suggestions accept "$SUGGESTION_ID"
# 5. Wait for article to complete
echo "Article writing started. Polling..."
while true; do
STATUS=$(balzac --json articles list --status done | jq -r 'length')
if [ "$STATUS" -gt "0" ]; then
echo "Article done!"
balzac articles list --status done
break
fi
sleep 10
done
#!/bin/bash
balzac --json suggestions list --status proposed | \
jq -r '.[].id' | \
while read -r id; do
echo "Accepting $id..."
balzac suggestions accept "$id"
sleep 1
done
#!/bin/bash
mkdir -p exports
balzac --json articles list --status done | \
jq -r '.[] | "\(.id) \(.slug)"' | \
while read -r id slug; do
echo "Exporting $slug..."
balzac articles export "$id" --format markdown --output "exports/${slug}.md"
done
# Write and wait for completion
balzac write "best AI writing tools 2026" --type listicle --length long --wait
| Variable | Required | Default | Description |
|---|---|---|---|
BALZAC_API_KEY | Yes* | None | Your Balzac API key (alternative to balzac auth login) |
BALZAC_API_URL | No | https://api.hirebalzac.ai/v1 | Custom API endpoint |
* Required unless stored via balzac auth login
| Action | Credits |
|---|---|
| Writing an article (accepting suggestion or creating briefing) | 5 |
| Generating 10 new suggestions | 1 |
| Rewriting an article | Free, 2 per article |
| Regenerating a picture (new cover) | Free, 2 per article |
The cover written with the article doesn't count toward its 2 new covers, and balzac articles get shows what an article has left (Rewrites Left, New Covers Left). Only one rewrite and one new cover can run at a time per article (409 conflict while one runs), and once an article has used its 2, the API returns 422 free_limit_reached. Check your available credits with balzac auth status.
The CLI provides clear error messages with colored output:
| Error | Solution |
|---|---|
No API key configured | Run balzac auth login or set BALZAC_API_KEY |
No workspace specified | Use -w <id> or balzac config set workspace <id> |
unauthorized | API key is invalid or expired |
insufficient_credits | Not enough credits: check your billing in the Balzac app |
not_found | Resource doesn't exist: check the ID |
conflict | Action not allowed (e.g. accepting an already accepted suggestion, or a rewrite or new cover already running) |
validation_failed | Invalid parameters: check the details in the error (e.g. a moved integration URL without its secret), or the message (e.g. an unknown --style) |
limit_reached | Keyword limit reached: upgrade plan or disable existing keywords |
free_limit_reached | The article has used its 2 free rewrites or 2 free new covers |
no_stock_photo | regenerate-picture --no-ai-images found no stock photo: try a few search words with --instructions, or --mode title |
stock_photo_unavailable | The stock photo search didn't answer in time (503): try again in a minute |
plan_limit_reached | Your plan's website limit is reached: upgrade, or delete a workspace you no longer need |
rate_limited | Too many requests: CLI auto-retries with backoff |
Exit codes:
The CLI maps to these Balzac API endpoints:
| CLI Command | Method | API Endpoint |
|---|---|---|
auth status | GET | /me |
workspaces list | GET | /workspaces |
workspaces create | POST | /workspaces |
workspaces get | GET | /workspaces/{id} |
workspaces update | PATCH | /workspaces/{id} |
workspaces delete | DELETE | /workspaces/{id} |
keywords list | GET | /workspaces/{id}/keywords |
keywords create | POST | /workspaces/{id}/keywords |
keywords enable | POST | /workspaces/{id}/keywords/{id}/enable |
keywords disable | POST | /workspaces/{id}/keywords/{id}/disable |
keywords generate | POST | /workspaces/{id}/keywords/generate |
suggestions list | GET | /workspaces/{id}/suggestions |
suggestions generate | POST | /workspaces/{id}/suggestions/generate |
suggestions accept | POST | /workspaces/{id}/suggestions/{id}/accept |
suggestions reject | POST | /workspaces/{id}/suggestions/{id}/reject |
briefings list | GET | /workspaces/{id}/briefings |
briefings create | POST | /workspaces/{id}/briefings |
articles list | GET | /workspaces/{id}/articles |
articles get |
Full API documentation: developer.hirebalzac.ai
src/
├── index.ts # CLI entry point with Commander
├── client.ts # BalzacClient API class
├── config.ts # Persistent config store
├── output.ts # Tables, JSON mode, spinners, colors
└── commands/
├── auth.ts # auth login/logout/status
├── workspaces.ts # Workspace CRUD
├── keywords.ts # Keyword management
├── suggestions.ts # AI suggestion management
├── briefings.ts # Briefing CRUD
├── articles.ts # Article CRUD + actions
├── write.ts # Shortcut: topic → article
├── competitors.ts # Competitor management
├── links.ts # Link management
├── settings.ts # Workspace settings
├── tones.ts # Tones of voice
└── config.ts # CLI config management
package.json
tsconfig.json
tsup.config.ts
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Run locally
node dist/index.js --help
# Auth
balzac auth login # Store API key
balzac auth status # Account, credits, role
# Workspaces
balzac workspaces list # List workspaces
balzac workspaces create --domain https://site.com --wait # Auto-setup
balzac workspaces get <id> # Get details
# Keywords
balzac keywords list # List keywords
balzac keywords create --name "keyword" # Add keyword
balzac keywords enable <id> # Enable
balzac keywords generate # AI generate
# Suggestions
balzac suggestions list --status proposed # Pending suggestions
balzac suggestions generate # Generate new (1 credit)
balzac suggestions accept <id> # Accept (5 credits)
# Briefings
balzac briefings create --topic "My topic" # Write article (5 credits)
# Articles
balzac articles list --status done # Completed articles
balzac articles get <id> # Live URL, publications
balzac articles rewrite <id> # Rewrite (free, 2 per article)
balzac articles regenerate-picture <id> # New picture (free, 2 per article)
balzac articles export <id> --format markdown # Export
balzac articles publish <id> --integration <int-id> # Publish
# Shortcut
balzac write "Topic here" --wait # Topic → article
# Config
balzac config set workspace <id> # Default workspace
balzac config get # Show all config
# Output modes
balzac --json workspaces list # JSON output
balzac -q articles list # IDs only
src/npm run buildMIT
| GET |
/workspaces/{id}/articles/{id} |
articles rewrite | POST | /workspaces/{id}/articles/{id}/rewrite |
articles regenerate-picture | POST | /workspaces/{id}/articles/{id}/regenerate_picture |
articles publish | POST | /workspaces/{id}/articles/{id}/publish |
articles schedule | POST | /workspaces/{id}/articles/{id}/schedule |
articles cancel-schedule | DELETE | /workspaces/{id}/articles/{id}/cancel_schedule |
articles export | GET | /workspaces/{id}/articles/{id}/export |
competitors list | GET | /workspaces/{id}/competitors |
competitors add | POST | /workspaces/{id}/competitors |
links list | GET | /workspaces/{id}/links |
links add | POST | /workspaces/{id}/links |
settings get | GET | /workspaces/{id}/settings |
settings update | PATCH | /workspaces/{id}/settings |
tones list | GET | /tones_of_voice |