Reference

Docs

Five tools — assess_ad_creative, assess_ad_batch, audit_campaign_structure, analyze_campaign_performance, strategize_targeting. Two front doors: MCP (Streamable HTTP) and REST. One key for both — create it in the dashboard.

Maintained by Dino S. · Founder, Spendict · Updated July 2026

Connect your agent

Drop in the agent Skill (recommended) and your agent gates every ad automatically — or connect over MCP, the CLI, or plain REST. Same five tools, same verdict, same quota.

1

Add the skill

Same SKILL.md works in Claude Code, Cursor, Codex, and Gemini.

npx skills add spendict/skills
2

Connect Spendict

The skill calls Spendict over MCP or the CLI — connect once (see the MCP or CLI tab).

3

Ship only winners

Your agent now gets a run / fix_first / kill on every ad before it recommends launching.

Using a framework? Copy-paste recipes for CrewAI, LangGraph, the Claude Agent SDK, n8n, and plain REST.

The five tools

Every tool is exposed over MCP at /api/mcp and mirrored one-for-one over REST. Same auth, same verdicts.

assess_ad_creativePOST /api/v1/assessrun / fix_first / kill on one ad creative
assess_ad_batchPOST /api/v1/assess-batchscore 2–20 variants → ranked best→worst
audit_campaign_structurePOST /api/v1/audit-campaignsound / fix_first / restructure on a build
analyze_campaign_performancePOST /api/v1/analyze-performancehealthy / fix_first / kill_or_rebuild / insufficient_data on live metrics
strategize_targetingPOST /api/v1/strategize-targetinga generated targeting strategy (structure-validated)

assess_ad_creative — gate the creative

The flagship. Judges an ad before a cent is spent and returns a deterministic verdict.

cat > ad.json <<'EOF'
{
  "ad_copy": {
    "primary_text": "Still paying an agency $3k/mo for ads a robot writes better?",
    "headline": "Fire your ad agency"
  },
  "platform": "meta",
  "format": "static",
  "product_context": "AI Meta-ads automation tool, $99/mo",
  "target_audience": "DTC founders spending $2-20k/mo on Meta ads"
}
EOF

curl -sS -X POST https://www.spendict.com/api/v1/assess \
  -H "Authorization: Bearer spd_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  --data @ad.json

The body goes in a file on purpose: real ad copy is full of characters shells mangle (apostrophes, !, $99). Inside <<'EOF' nothing is interpreted, and --data @ad.json sends it byte-for-byte.

Input

ad_copy.primary_textstring · requiredThe main ad body or video script.
ad_copy.headlinestringOptional headline.
ad_copy.descriptionstringOptional description / subtext.
creative_urlhttps URLOptional image or video-frame URL — enables visual assessment.
platformmeta | tiktok | google | linkedin | youtube · requiredAssessment is platform-specific.
product_contextstring · requiredWhat's being sold, the offer, the key value.
target_audiencestringWho it's for, if known.
formatvideo | static | carouselDefaults to static.

The verdict

Scores are 0–100 across seven dimensions (hook, angle, clarity, audience_resonance, platform_fit, cta, compliance_safety) plus an authoritative, deterministic launch_recommendation:

  • run — worth spending on: overall ≥ 78, hook ≥ 60, no hard gate tripped.
  • fix_first — a real spine but a specific fixable problem; the fixes are the path to run. A dead hook or a likely policy rejection always caps an ad here.
  • kill — structurally broken (two or more failing fundamentals); faster to regenerate than to fix.
{
  "overall_score": 78,
  "launch_recommendation": "run",
  "dimension_scores": {
    "hook": 78, "angle": 80, "clarity": 82,
    "audience_resonance": 80, "platform_fit": 85,
    "cta": 0, "compliance_safety": 95
  },
  "predicted_failure_mode": "No material weakness — would run as-is.",
  "prioritized_fixes": [],
  "enhancements": [
    { "issue": "No conversion path (CTA scored 0)",
      "suggestion": "Add one clear next step — optional; ships as-is." }
  ]
}

assess_ad_batch — which of N to run

Your agent generates 100 variants an hour; this says which few to run. Score 2–20 variants that share one campaign context in a single call and get them back ranked — same seven-dimension scoring and the same deterministic verdict as assess_ad_creative (a variant scored in a batch is identical to scoring it alone).

curl -sS -X POST https://www.spendict.com/api/v1/assess-batch \
  -H "Authorization: Bearer spd_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform": "meta",
    "product_context": "AI Meta-ads automation tool, $99/mo",
    "target_audience": "DTC founders spending $2-20k/mo on Meta ads",
    "variants": [
      { "label": "v1", "ad_copy": { "primary_text": "Still paying $3k/mo for ads a robot writes better?" } },
      { "label": "v2", "ad_copy": { "primary_text": "Introducing our new ad platform for teams." } }
    ]
  }'

Input

platform / product_contextstring · requiredShared campaign context, applied to every variant.
target_audiencestringOptional shared context.
formatvideo | static | carouselDefault for all variants; a variant can override.
variants[]array · 2–20 · requiredEach: ad_copy (+ optional label, creative_url, format). One quota per variant.

The response

Variants ranked by verdict (run > fix_first > kill) then overall score, a summary count, and per-variant errors (e.g. if quota runs out partway). Take the top N run and launch them.

{
  "summary": { "total": 2, "assessed": 2, "failed": 0,
    "run": 0, "fix_first": 1, "kill": 1, "top_label": "v1" },
  "ranked": [
    { "rank": 1, "label": "v1", "launch_recommendation": "fix_first", "overall_score": 74, ... },
    { "rank": 2, "label": "v2", "launch_recommendation": "kill", "overall_score": 46, ... }
  ],
  "errors": []
}

audit_campaign_structure — audit the build

Judges a campaign's structure by the correct platform's rulebook before budget flows through it. Verdict: sound / fix_first / restructure.

platformmeta | google | tiktokRequired.
objectivestringRequired — defines 'correct structure'.
campaign_structurestringRequired — the build to audit.
total_budget / funnel_stagestringOptional context.

analyze_campaign_performance — diagnose live

Judges real metrics against benchmarks and finds the one bottleneck. Verdict: healthy / fix_first / kill_or_rebuild / insufficient_data.

platform / objectivestringRequired — set the benchmarks.
metricsobjectRequired — the real campaign numbers.
linked_assessmentsobjectOptional — reconcile vs pre-flight prediction.
campaign_identifierstringOptional — auto-match fallback.

strategize_targeting — design the plan

The generative tool. Given a product, budget, and objective, it returns one opinionated, executable targeting strategy — audience approach, segmentation, exclusions, a budget split with a learning-phase check, setup notes, and the single biggest risk. No score here; the server validates the structure of the returned plan.

platform / product / budget / objectivestringRequired.
funnel_stage / verticalstringOptional — axes of justified segmentation.
audience_data / geo_languagestringOptional — thin data → lower confidence.

Errors

Always JSON — { error, message }, never a stack trace.

400invalid_input / invalid_json / empty_bodySchema details; not counted.
401missing_api_key / invalid_keyCheck the Authorization header.
429quota_exceededIncludes upgrade_url; not a crash.
502 / 503model_error / config_errorNot counted; retry.

Quotas

Free: 100/mo · Starter ($19): 1,500/mo · Pro ($49): 5,000/mo · Scale ($199): 25,000/mo. Every tool call counts equally. The quota check happens before inference; failed calls are refunded. Median latency is a few seconds — size your agent's tool timeout to ~30s.