# Build with ReachPill — a guide for AI coding agents

You are an AI coding agent (Claude, Cursor, or similar) integrating **ReachPill** into a codebase. ReachPill turns a product's own brand and events into on-brand content — social posts, blog articles, images — published to the channels or repo the team already uses. It is API- and MCP-native: everything below runs from code, no dashboard required.

**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.

- **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 a `mg_live_`/`mg_test_` key as a bearer token). Every capability below is also an MCP tool — prefer MCP when you're operating as an agent.
- **OpenAPI spec:** `https://app.reachpill.com/openapi.yaml`

---

## 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)

```bash
# 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 candidates
```

MCP: `derive_brand({url})` → `get_brand_derivation({})`.

Then save what you want to keep:
```bash
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)

```bash
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

```bash
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)

```bash
# 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:
```bash
# 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:
```bash
# 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`):
```yaml
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` (supports `brand`, `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`.
