Skip to content

Usage Analytics with a Custom API

If you already aggregate product usage in your own systems — internal data warehouse, billing platform, document-processing pipeline, anything that can serve a JSON endpoint — Clynto can pull from it directly. No Mixpanel required.

This guide walks you through connecting your endpoint, mapping its response to Clynto's usage shape, and what happens after.


What you get

Once a Custom API source is connected, the metrics you wire up flow into the same places Mixpanel data does:

  1. Health score — the Adoption and Engagement pillars use your metrics to score accounts. An account that hasn't generated any of the metric values you tracked drops; one that's growing gets credit.
  2. Usage tab on every account — your custom metrics show up alongside event totals, with a 30-day daily breakdown.
  3. Workspace tableUsage (30d) and other usage-derived columns light up using your data.
  4. Churn signals — usage-decline signals evaluate your metrics with the same logic they use for Mixpanel-sourced data.
  5. Larry — when Larry explains a usage-related signal or answers questions like "how is Acme using the product?", the answer references the metrics you defined by name.

You define the metric names yourself (e.g. documents_uploaded, api_calls, active_seats). They show up in the UI and in Larry's responses with the names you chose.


Custom API or Mixpanel?

Pick one usage source per workspace — Clynto enforces this so health scores and signals don't double-count.

Pick Mixpanel if… Pick Custom API if…
Your product already sends events to Mixpanel You don't use Mixpanel, or your "real" usage data lives elsewhere
You care about per-seat metrics (active users, stickiness) Daily totals per account are enough — you don't need user-level granularity
You want pre-built event-volume + DAU/MAU dashboards out of the box You want full control over which metrics matter for your product

You can disconnect one and connect the other later — historical data is preserved either way.


Before you start

You'll need:

  • Admin or Owner role in your Clynto workspace.
  • A URL that returns daily usage data as JSON. It should accept a date range — typically as query parameters like ?from=2026-04-01&to=2026-05-01 — and return data scoped to that range.
  • Authentication credentials for the URL. Clynto supports:
    • API key in a header (e.g. X-API-Key: secret)
    • Bearer token (Authorization: Bearer …)
    • Basic auth (username + password)
    • API key in a query parameter
    • No auth (open endpoint)
  • An account identifier in the response that matches Clynto's external_crm_id (the same ID you have on each account, usually from your CRM). If the response uses a different identifier, you'll need to map it on the CRM side first.
  • A list of the metrics you want to track, in plain English. Examples: "documents uploaded per day", "billable api calls", "active integrations connected".

Setup walkthrough

Two steps total. Most teams finish in 5–10 minutes.

Step 1 — Connect

  1. Go to Integrations in the left nav.
  2. Find the Custom API card under the Analytics section and click Connect Custom API.
  3. Fill in the connection form:
    • Endpoint URL — the full URL. Use the placeholders {start_date} and {end_date} wherever your API expects a date range. Example: https://api.example.com/usage?from={start_date}&to={end_date} Clynto substitutes those placeholders with YYYY-MM-DD dates each time it calls your endpoint (last 7 days for the connect test, last 30 days for the initial backfill, yesterday-only for the daily refresh).
    • MethodGET for most APIs. POST is supported but the body isn't templated yet.
    • Authentication — pick the type and fill in the matching fields.
    • Timeout — how long to wait for a response. Default 30s, max 60s. Bump it if your endpoint is slow on the 30-day pull.
  4. Click Test & Continue.

Clynto calls your endpoint with a 7-day date range to verify the credentials and URL work. If anything's wrong — wrong header name, expired token, URL typo — you'll see an inline error explaining what failed. Fix and retry.

On success, the raw JSON response is captured (truncated at 8KB if huge) and used to drive the next step.

Step 2 — Map fields

The Mapping modal opens automatically after a successful connect. You're telling Clynto where in the response to find each piece of data it needs.

The expected output is one row per (date, account, metric set) — Clynto turns your response into a flat list shaped like:

json [ {"date": "2026-05-06", "external_crm_id": "cust_123", "metrics": {"documents_uploaded": 42, "api_calls": 1500}}, {"date": "2026-05-06", "external_crm_id": "cust_456", "metrics": {"documents_uploaded": 8, "api_calls": 220}} ]

You provide the paths Clynto should walk to extract each field. Paths use JMESPath — a small query language for JSON. The most common patterns:

Goal JMESPath
Top-level array (response is the list) @
Field one level deep data
Nested field data.usage
Same field within each row just the field name, e.g. customer_id

The fields you'll fill in

  • Rows path — the JMESPath that gets you to the array of records. Use @ if your response is already an array, data.usage if it's nested, etc.
  • Date path — relative to one row, where to find the date. Usually date, day, or timestamp.
  • Date format — pick from:
    • YYYY-MM-DD (e.g. "2026-05-06")
    • ISO 8601 (e.g. "2026-05-06T10:00:00Z")
    • Unix epoch in seconds
    • Unix epoch in milliseconds
  • Account ID path — relative to one row, where to find the account identifier. This must match the external_crm_id value Clynto already has from your CRM.
  • Metrics — each metric has a name (snake_case, your choice — this is the name that appears in the UI) and a path (relative to one row, where the numeric value lives). You can add up to 25 metrics.

Use AI to fill the form

Above the form there's a Describe each metric textarea. Type one description per line in plain English:

documents uploaded per day billable api calls

Click Suggest with AI. Clynto sends your sample response plus your descriptions to its AI model and fills in the form for you. Always review what it filled in — the AI is good but it can pick the wrong field if your response has ambiguous names. Use the form as a starting point, not the final answer.

Preview before saving

Click Run preview to apply the mapping to your sample response and see the output:

  • A table of the first 10 rows with date, account, and metric values
  • Any errors (missing fields, bad dates, non-numeric metric values) per row

If the preview looks right and there are no errors, click Save & Backfill 30 days. The modal closes and Clynto pulls 30 days of historical data from your endpoint. Backfill usually takes under a minute since it's a single API call.

When backfill completes, the card flips to Connected and your health scores will start incorporating the data on the next computation cycle.


What you'll see after setup

On the Custom API card

  • Metrics tracked — how many of your 25 metric slots are configured.
  • Last sync — when the daily refresh last ran successfully.
  • Unmatched accounts — count of account identifiers we couldn't resolve to a Clynto account. Some unmatched is normal (test rows, accounts not yet in your CRM); a high or growing count usually means your account ID column doesn't quite match what's in external_crm_id.
  • Sync now button — triggers an immediate refresh. Useful right after fixing a mapping or if you want to verify a recent change to your endpoint without waiting until tomorrow.
  • Reconfigure — reopens the mapping modal so you can adjust paths, add/remove metrics, or change the date format.
  • Disconnect — stops syncing. Existing usage history stays in place; reconnect with the same or a different endpoint to resume.

Everywhere else

The data shows up in the same places Mixpanel data does — Usage tab on each account detail, dashboard columns, Health pillars, churn signals, and Larry chat. The metric names you defined appear verbatim in those views.


Daily updates

After the initial 30-day backfill, Clynto refreshes Custom API data once a day:

  • Daily sync runs at 5:15 AM UTC for every connected workspace
  • It pulls yesterday's data only ({start_date} and {end_date} are both set to yesterday)
  • Health scores recompute automatically within ~15 minutes of new data landing
  • Churn signals re-evaluate on each workspace's normal signal schedule

Click Sync now on the card any time you want to refresh immediately rather than wait for the nightly run.


Troubleshooting

Connection test fails

Most "Test & Continue" failures fall into a few buckets:

  • HTTP 401 / 403 — credentials are wrong. Double-check the header name, token, or username/password.
  • HTTP 404 / 500 — the URL is wrong, or the date range we sent (last 7 days) doesn't match what your endpoint expects.
  • Timeout — your endpoint took longer than the timeout you configured. Bump the timeout slider before retrying.
  • "Response is not valid JSON" — your endpoint returned HTML, XML, or plain text. Custom API only consumes JSON.

The error message in the modal usually tells you which one.

Preview shows "rows_path returned no data"

The path you gave doesn't reach an array. Click Show API response sample at the top of the mapping modal and trace the structure manually — common culprits are typo'd field names or forgetting to drill down through a wrapper object (e.g. using data when the array is at data.results).

Preview shows lots of per-row errors

The mapping is reaching rows but extracting bad data:

  • "date: …" — your date_path is wrong, or the date format dropdown doesn't match what's in the response (e.g. you picked YYYY-MM-DD but the response has Unix timestamps).
  • "metric X: not numeric" — the path resolves to something other than a number. Check whether the field is a string that needs trimming, a wrapped object like {"value": 42} (use field.value to dig in), or simply the wrong field.
  • "account_id missing or empty" — your account_id_path is wrong, or some rows in the response don't have an account ID. Rows missing account IDs are skipped; that's usually fine, but if it's most of them, the path needs fixing.

High "Unmatched accounts" count on the connected card

Your endpoint is returning account IDs that don't exist in external_crm_id on any Clynto account. Three common causes:

  1. The CRM hasn't synced those accounts yet. They'll match automatically on the next CRM sync — Clynto re-runs the resolution nightly against your current account list.
  2. The IDs in your endpoint use a different format from your CRM (e.g. internal database IDs vs. HubSpot IDs). You'll need to align them on the source side.
  3. You picked the wrong field in the response. Reconfigure and pick a different account_id_path.

Hard error banner (red)

Custom API has switched into the error state. Possible causes:

  • Credentials rotated and the daily sync started failing.
  • Your endpoint changed its response shape (a field got renamed, an array became an object).
  • Your endpoint is down.

Click Reconnect to re-test the URL and credentials. If the test passes, run Sync now to confirm the daily flow works again.

"Usage data hasn't synced in Xh" (yellow)

The daily sync hasn't completed in over 36 hours. Check the error message under the banner; if it points at credentials or your endpoint, fix it on your side and either reconnect or hit Sync now. If neither, contact support.


Frequently asked questions

How does the AI suggest button know my data? Your sample response (the JSON your endpoint returned during the connect test) is sent to Clynto's AI model along with your plain-English metric descriptions. The model emits a suggested mapping that you review and edit. The sample is not retained beyond setup — it's cleared from our database the moment you save the mapping.

Can I send anything other than numbers as metric values? No. Metric values must be numeric (integers or floats). Categorical values like "tier=premium" or "region=us-east" don't fit the usage-data shape — those belong on the Account model itself, set via your CRM sync.

My response is nested by date instead of being a flat list. Can I still use it? Yes, but you'll need a JMESPath expression in Rows path that flattens the structure. JMESPath supports multi-select hashes that turn {"2026-05-06": {"cust_1": {"docs": 5}}} into a flat list. If you can't get it working, try the AI suggest button — it's surprisingly good at flatten patterns. If that still doesn't work, the simplest fix is to reshape the response on your side.

What if my endpoint paginates? Today (v1), Clynto expects a single response — no pagination. If your endpoint returns more than fits in one call, either reduce the date window (the daily sync only asks for one day) or aggregate the data on your side before serving it. Pagination support is on the roadmap.

Can I connect more than one Custom API endpoint? One per workspace. If you need to combine multiple sources, do the combining on your side and serve the merged result from a single URL.

Is my API key encrypted? Stored the same way as our other integration credentials (HubSpot, Stripe, Freshdesk). Treat it like any other secret you give us — rotate it on your side any time and reconnect.

What format do dates need to be in the URL placeholders? {start_date} and {end_date} are always substituted as YYYY-MM-DD. If your endpoint expects a different format (e.g. ISO 8601 with time, or Unix epoch), you'll need to handle the conversion on your side — usually by accepting YYYY-MM-DD as a query param and parsing it inside your code.

Does my endpoint need to be public? It needs to be reachable from Clynto's infrastructure. If it's behind your firewall, you'll need to allowlist Clynto's egress IPs — contact support for the current list. If it's behind a corporate VPN, this integration won't work; you'd need to either expose a tunneled or proxied version, or fall back to Mixpanel.

How quickly does data show up after my endpoint changes? The daily sync runs at 5:15 AM UTC and pulls yesterday's data. So an event that happens on Monday in your system shows up in Clynto on Tuesday morning. Click Sync now to refresh immediately, or reduce the gap by ensuring your endpoint serves yesterday's data as soon as your own pipeline finalizes it.


Need help?

If something's not working and the troubleshooting above doesn't cover it, contact support and include:

  • Your workspace name
  • The exact text of any error or banner shown on the Custom API card
  • The endpoint URL (we'll never call it without your permission, but knowing the shape helps us help you)
  • A redacted sample of what your endpoint returns

We can pull the integration's recent sync history from our side and tell you what failed.