Build with agents
ReachPill is API- and MCP-native — everything on this page runs from code, no dashboard required. Hand the whole integration to a Claude or Cursor agent: it can set it up, run the test-first workflow below, and verify the loop end to end on its own, before a human ever touches a live key.
/llms.txt first will find both this page and the raw guide linked from reachpill.com/llms.txt.The basics
- Base URL:
https://app.reachpill.com/v1 - Auth:
Authorization: Bearer <api_key>on every request. - MCP server:
https://app.reachpill.com/mcp(OAuth 2.1, or anmg_live_/mg_test_key as a bearer token). Every capability below is also an MCP tool — prefer MCP when operating as an agent. - OpenAPI spec:
https://app.reachpill.com/openapi.yaml
The golden rule: build and test with a test key first
Test keys are free, instant, and deterministic — no credits, no real posts. Only swap to a live key once the loop works end to end.
The test-first workflow
Get a test key
One-time, by a human: mint an mg_test_ key in Settings → Billing → API keys.
Derive the brand
Point brand-derivation at the product's own site instead of hand-authoring a brand kit.
Dry-run an image
See the grounded prompt, references and cost estimate — spend nothing.
Generate for real, free
The same call, without dry_run: an instant deterministic placeholder, zero credits.
Publish to a sandbox channel
No OAuth: schedule a post to a simulated connection and watch it reach published.
Wire up release autopilot
Announce a release and get on-brand posts and a blog post automatically.
Go live
Swap mg_test_ for mg_live_, connect real channels, drop dry_run. Everything else is identical.
0. Get keys (the human does this once)
Ask the user to create two API keys in ReachPill → Settings → Billing → API keys:
- a test key (
mg_test_…) — mint it with the "test" toggle, - a live key (
mg_live_…) for production.
Test keys are the whole point of a friction-free setup: a mg_test_ key runs generations against instant deterministic placeholders and publishes to a simulated channel — free, no side effects.
1. Define the brand (from a URL, not by hand)
# Kick off derivation from the product's own site.
curl -s https://app.reachpill.com/v1/brand-derivation \
-H "Authorization: Bearer $RP_TEST_KEY" -H "Content-Type: application/json" \
-d '{"url":"https://theproduct.com"}'
# → { "id": "...", "status": "pending" }
# Poll until completed.
curl -s https://app.reachpill.com/v1/brand-derivation/latest \
-H "Authorization: Bearer $RP_TEST_KEY"
# → status: completed, plus voice, palette, imagery_style, logo candidatesMCP: derive_brand({url}) → get_brand_derivation({}).
Then save what you want to keep:
curl -s -X PUT https://app.reachpill.com/console/... /brand-kit # or MCP:
# update_brand_kit({ imagery_style, color_scheme, fonts, logo:[...] })update_brand_kit sets the entire visual identity from code — imagery style, hex palette, font directives, up to 4 logo variants, mascot reference images (all URL-based). Note: its array fields (logo, references, terminology, facts) are full-replacement— read-modify-write, don't send a partial.
2. Dry-run an image (see the grounded prompt, spend nothing)
curl -s https://app.reachpill.com/v1/generations \
-H "Authorization: Bearer $RP_TEST_KEY" -H "Content-Type: application/json" \
-d '{"type":"image","tier":"standard","prompt":"our launch announcement","brand":true,"dry_run":true}'
# → { "dry_run": true, "resolved_prompt": "...brand DNA folded in...",
# "reference_image_urls": [...], "brand_mark_composited": true,
# "estimated_credits": N }dry_run:true resolves everything — the brand-grounded prompt, the exact references and brand mark, the model, the estimate — and generates nothing. Use it to verify the brand setup and to show the user how their DNA grounds a prompt.
MCP: create_generation({ ..., brand: true, dry_run: true }).
3. Generate for real — free — with the test key
curl -s https://app.reachpill.com/v1/generations \
-H "Authorization: Bearer $RP_TEST_KEY" -H "Content-Type: application/json" \
-d '{"type":"image","tier":"standard","prompt":"our launch announcement","brand":true}'
# → { "job_id": "...", "status": "succeeded", "test": true } (instant placeholder)With a test key the job completes immediately against a deterministic placeholder image — no provider call, no credits. Poll GET /v1/generations/{job_id} for its output URL (works exactly like a live job).
4. Test the publish loop with a sandbox channel (no OAuth)
# Create a simulated channel — no OAuth, no real account.
curl -s https://app.reachpill.com/v1/social/sandbox-connections \
-H "Authorization: Bearer $RP_TEST_KEY" -H "Content-Type: application/json" \
-d '{"platform":"x"}'
# → a connection you can target
# Schedule a post to it → it "publishes" in simulation with a deterministic URL.
curl -s https://app.reachpill.com/v1/social/posts \
-H "Authorization: Bearer $RP_TEST_KEY" -H "Content-Type: application/json" \
-d '{"caption":"We just shipped v2!","media":["gen:<job_id>"],
"targets":[{"connection_id":"<sandbox_conn_id>"}],"schedule":"now"}'MCP: create_test_channel({platform}), then schedule_social_post(...). Poll get_social_post and watch it reach published — with zero real posting.
5. Wire up release-driven content (the headline use case)
Make every product release become on-brand posts automatically:
# Configure autopilot for a repo.
curl -s https://app.reachpill.com/v1/release-sources \
-H "Authorization: Bearer $RP_LIVE_KEY" -H "Content-Type: application/json" \
-d '{"repo_full_name":"acme/app","review_mode":"auto_publish",
"platform_targets":[{"platform":"x"},{"platform":"linkedin"}],"produce_blog":true}'Then either drop a GitHub Action into the repo that POSTs releases (you hold no GitHub access), poll the public releases feed, or install the read-only GitHub App. Or announce directly:
# MCP: announce_release({ repo_full_name, tag, title, body_markdown })
curl -s https://app.reachpill.com/v1/release-events \
-H "Authorization: Bearer $RP_LIVE_KEY" -H "Content-Type: application/json" \
-d '{"repo_full_name":"acme/app","tag":"v2.0.0","title":"v2","body_markdown":"...notes..."}'The first release always waits for a human review; from the second on it's hands-off. Content leads with what changed vs. the previous version, and won't re-announce what already shipped.
GitHub Action snippet (drop in .github/workflows/reachpill.yml):
on: { release: { types: [published] } }
jobs:
announce:
runs-on: ubuntu-latest
steps:
- run: |
curl -sf https://app.reachpill.com/v1/release-events \
-H "Authorization: Bearer ${{ secrets.REACHPILL_KEY }}" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg repo '${{ github.repository }}' \
--arg tag '${{ github.event.release.tag_name }}' \
--arg title '${{ github.event.release.name }}' \
--arg body '${{ github.event.release.body }}' \
'{repo_full_name:$repo,tag:$tag,title:$title,body_markdown:$body}')"6. Go live
When the sandbox loop works: switch mg_test_ → mg_live_, have the user connect real channels (social OAuth, or a blog destination: GitHub repo / webhook / HubSpot), and drop dry_run. Everything else is identical.
Full MCP tool set
- Brand:
get_brand_kit,update_brand_kit,derive_brand,get_brand_derivation,get_project,update_project. - Generate:
create_generation(supportsbrand,dry_run),create_composition,create_carousel,estimate_cost,list_models,get_generation. - Publish:
schedule_social_post,update_social_post,list_social_posts,create_test_channel,create_blog_post,generate_blog_post,publish_blog_post. - Releases:
create_release_source,list_release_sources,announce_release. - Campaigns:
create_campaign,plan_campaign_arc,preview_campaign,list_campaign_occurrences,approve_occurrence. - Account:
get_balance,get_usage_summary,get_spend_breakdown.