All jobs

Summarize Each Customer's Product Usage From PostHog Through an API

Yes. Your backend starts one session per account; the agent reads that account's PostHog events and returns a JSON usage summary to your webhook.

What the agent does

This job has no repository. The agent's only source is your PostHog project, reached through PostHog's own MCP server at https://mcp.posthog.com/mcp, which Rush lists as a connector that signs in with OAuth. You connect it once with the API key: POST /me/connections with {"type": "mcp", "name": "posthog", "url": "https://mcp.posthog.com/mcp", "auth": {"mode": "oauth"}} answers 202 with an authorize_url, which the key's creator opens while signed in to the Rush console, and GET /me/connections/<id> reads status: "connected" once PostHog has approved it. A key run gets only the connections it names, so each request names this one, either with "connections": ["posthog"] beside the fields shown below, or by saving an agent with POST /o/{org}/agents whose connections list posthog and sending that agent's id as agent.

Your backend then starts one session per account. The input is the same instructions every time with one line that changes, the account's PostHog group key, so the prompt reads the same for every customer and only the subject differs. The agent uses the connection's query tools to find events attributed to that group over the last 30 days and the 30 days before, counts distinct users for active_users, ranks events or feature-flagged features by count for top_features, compares the two windows for trend, and writes risks from what it sees, such as a drop in active users or a feature that stopped being used.

The answer is the JSON object the prompt describes, as the turn's final message. Rush has no field that enforces a response schema (output_schema is 400 FIELD_REMOVED), so the shape lives in the prompt, and your server parses and validates result before storing it. The prompt also says read only: the PostHog MCP server can create insights and dashboards as well as query, and the session transcript at GET /o/{org}/sessions/{id}/messages lists every tool_use with its args, so you can check that a run called only reading tools.

To keep a retry from starting a second run for the same account, send an Idempotency-Key header such as the account id and the date: the same key and body return the session it first started, and a new day gets a new key.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Summarize product usage for the account whose PostHog group key follows this prompt. Use the PostHog connection to read its events from the last 30 days. Return JSON with `active_users`, `top_features` (5, with counts), `trend` (up, flat or down versus the 30 days before) and `risks` (short strings). Read only.\n\nGroup key: <account group key>"
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

Each session ends with one JSON object as its answer. Rush POSTs run.completed to the webhook URL on the API key within about 30 seconds of the turn ending, with data.result holding that answer (included up to 16 KiB, which a summary of this shape stays well under), data.status, data.total_cost_usd and data.session_url. A run.failed event means the run did not finish, for example because the PostHog connection needs signing in again, and GET on session_url with the key returns the error.

Your server matches the event to the account through the execution_id it got when it started the session, validates the JSON, and stores it beside the account record, where a customer-success tool can show it before a call. Requests to the webhook are signed per Standard Webhooks, so verify webhook-signature against the raw body and drop duplicates by webhook-id, since a failed delivery is retried up to three times.

Before relying on the summaries, check a few by hand against PostHog for the same group and window, confirm that the events counted as features are ones your team considers features rather than page views or system events, and read one transcript to see which queries the agent ran. Tighten the prompt with the event names you care about if the top five drift between runs.

Run it on every account renewal approaching

Run it on a schedule from your own backend: a daily job selects the accounts whose renewal or quarterly review falls in the next two weeks and sends one request per account. A key runs at most max_concurrent sessions at once (4 by default) and answers 429 past that, so the job queues the rest and starts the next session when a webhook says one finished.

For a summary on demand, start the session from your customer-success tool when someone opens an account, and show the result when the webhook arrives; the session URL also gives the live event stream at GET /o/{org}/sessions/{id}/events if the screen should show progress.

The use case this job follows, with its automation and trigger: Run an agent per customer task.

Why run it on Rush?

A per-account summary is a small piece of analysis repeated hundreds of times, and running it from a laptop or a cron box means holding your PostHog credentials there and writing the queries and the summarising yourself. On Rush each account gets its own session in its own sandbox, the PostHog sign-in stays in Rush's connection rather than in your job's environment, and your backend only sends a prompt and receives a webhook.

Each summary comes with its record. The transcript keeps every query the agent made through the connection and what PostHog returned, so a surprising trend or risk can be traced to the numbers behind it, and the webhook carries total_cost_usd per account, so you know what each summary cost.

Frequently asked questions

Can I be sure it only reads from PostHog?

The prompt tells it to read only, and the transcript at GET /o/{org}/sessions/{id}/messages lists every tool call with its arguments, so you can check that no create or update tool was used. For a stronger limit, connect PostHog with a user or project whose PostHog permissions are read-only; the connection can then do no more than that user can.

What if my PostHog project does not use group analytics?

Then there is no group key to filter on. Change the line the prompt reads to whatever identifies an account in your events, such as a company_id person or event property, and say in the prompt which property it is. The rest of the request stays the same.

How do I get the JSON back reliably?

Ask for it in the prompt, as here, and validate data.result on your server before using it. If a result does not parse, send a follow-up to the same session with POST /o/{org}/sessions/{id}/messages asking for the corrected JSON; the sandbox wakes where it left off, with the queries it already ran.

Does every run need its own PostHog sign-in?

No. You connect PostHog once with POST /me/connections, and every run that names the connection, or every run of a saved agent that lists it, uses that same sign-in. If PostHog revokes it, the connection reads needs_reauth and the key's creator signs in again once.