Developers

Grotivo API reference

Connect in-house systems, a data warehouse, ERP or custom CRM, to Grotivo. Push your numbers in, read growth insights out, and subscribe to signed events. If you use off-the-shelf tools like HubSpot, you may not need the API at all: an admin can connect them from the Integrations page with no code.

Use Grotivo in Claude, ChatGPT and other AI assistants

Grotivo has a connector built on the Model Context Protocol (MCP). Add it to Claude, ChatGPT or any assistant that supports MCP connectors, sign in to Grotivo and click Allow. The assistant can then read your Growth Score, numbers, recommendations, projects, tasks, reports and store sales, ask your Growth Advisor for advice, start projects and update tasks, always as you and with your role's permissions. Disconnect it any time in Grotivo under AI assistants & API.

Connector address:  https://www.grotivo.com/mcp
Sign-in:            OAuth 2.1 with PKCE (the assistant opens Grotivo's sign-in for you)
Tools:              get_growth_overview, list_recommendations, ask_growth_advisor,
                    update_recommendation, start_project, list_projects, list_my_tasks,
                    update_task, list_reports, get_report, generate_report,
                    analyse_report, add_business_numbers, get_store_performance

Authentication

Admins create keys in API & webhooks in Grotivo. Keys start with gtv_live_, are shown once and stored hashed. Send the key in the Authorization header over HTTPS, from your server only.

Authorization: Bearer gtv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PermissionAllowsPlans
metrics:writePush metricsAll plans
insights:readRead metrics, Growth Score, recommendationsGrowth, Scale, Enterprise

Push metrics

POST /api/v1/metrics, up to 500 items per request. period is the first day of the month (YYYY-MM-DD). department is optional (defaults to company-wide). Sending the same metric, period and department again updates the value.

curl -X POST https://www.grotivo.com/api/v1/metrics \
  -H "Authorization: Bearer $GROTIVO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metrics": [
      { "metric": "revenue",        "value": 125000, "period": "2026-09-01" },
      { "metric": "new_customers",  "value": 42,     "period": "2026-09-01", "department": "Sales" },
      { "metric": "retention_rate", "value": 91.5,   "period": "2026-09-01" }
    ]
  }'

Response: 200 { "received": 3 }

Standard metrics: revenue, new_customers, active_customers, retention_rate, churn_rate, pipeline_value, marketing_spend, marketing_roi, cac, gross_margin, operating_expenses, nps. Any other snake_case name is stored as a custom metric.

Read insights

GET /api/v1/growth-score
Response: { "growthScore": 72, "previousScore": 66, "pillars": [ { "area": "acquisition", "score": 3, "previous": 2 }, ... ],
    "strongest": "retention", "needsAttention": "acquisition" }

GET /api/v1/recommendations?status=approved
Response: { "recommendations": [ { "id": 18, "department": "Marketing", "title": "...", "action": "...",
    "impact": "...", "confidence": 88, "horizonDays": 30, "status": "approved" } ] }

GET /api/v1/metrics?from=2026-01-01&to=2026-09-30
Response: { "metrics": [ { "department": "Company", "metric": "revenue", "value": 125000, "period": "2026-09-01", "source": "api" } ] }

Webhooks

Available on Scale and Enterprise. Grotivo sends a POST with a JSON body to your HTTPS endpoint for: recommendation.created, report.generated, assessment.completed, metrics.received. Every request is signed with your endpoint's whsec_ secret.

Grotivo-Event: recommendation.created
Grotivo-Signature: t=1790000000,v1=5f2b…(hex HMAC-SHA256)

// Node.js verification
import crypto from "node:crypto";
const [t, v1] = req.headers["grotivo-signature"].split(",").map(p => p.split("=")[1]);
const expected = crypto.createHmac("sha256", process.env.GROTIVO_WEBHOOK_SECRET)
  .update(`${t}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
if (!fresh || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) return res.status(401).end();

Errors

Errors return JSON { "error": "message" } with status 400 (invalid input), 401 (missing or revoked key), 402 (subscription inactive), 403 (permission or plan), 409 (conflict) or 5xx.

Security checklist