Skip to content

feat: new guide - Connect Loops to Kinde#663

Merged
tamalchowdhury merged 9 commits intomainfrom
tamal/feat/kinde-and-loops-integration
Feb 13, 2026
Merged

feat: new guide - Connect Loops to Kinde#663
tamalchowdhury merged 9 commits intomainfrom
tamal/feat/kinde-and-loops-integration

Conversation

@tamalchowdhury
Copy link
Collaborator

@tamalchowdhury tamalchowdhury commented Feb 4, 2026

Description (required)

This doc creates a new guide, connect Loops to Kinde (via Zapier)

Related issues & labels (optional)

  • Closes #
  • Suggested label:

Summary by CodeRabbit

  • Documentation
    • Added a beginner-friendly, step-by-step guide for integrating Kinde webhooks with Loops via Zapier (includes JWT decoding examples, contact field mappings, NDJSON→CSV import workflow, testing, and publish guidance).
    • Updated Kinde Mailgun delivery webhook payload field names/order.
    • Updated send-invitations webhook payload: user attributes nested under a user object and source moved to top level.

@gitguardian

This comment was marked as resolved.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

Important

Review skipped

This PR was authored by the user configured for CodeRabbit reviews. By default, CodeRabbit skips reviewing PRs authored by this user. It's recommended to use a dedicated user account to post CodeRabbit review feedback.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)

Walkthrough

Adds a new MDX documentation page describing how to connect Kinde webhooks to Loops via Zapier (Catch Raw Hook → Code action to decode JWT → Loops API create/update contact), and updates two existing webhook docs to reflect payload field changes.

Changes

Cohort / File(s) Summary
New documentation page
src/content/docs/integrate/third-party-tools/kinde-loops.mdx
Adds a beginner-oriented integration guide: front matter, prerequisites, step-by-step Zapier setup (Catch Raw Hook → Code action to decode JWT → Loops create/update contact), inline JS JWT decoder, detailed Loops field mappings, testing/publish instructions, and an NDJSON→CSV import workflow with Python script.
Kinde Mailgun payload update
src/content/docs/integrate/third-party-tools/kinde-mailgun-email-delivery.mdx
Adjusts webhook payload schema: replaces user_id with id inside user and reorders last_name after first_name.
Send invitations webhook payload change
src/content/docs/manage-users/add-and-edit/send-invitations-webhook.mdx
Modifies payload structure: removes top-level id; nests user attributes under data.user (email, first_name, last_name, id); moves source from data to a top-level field.

Sequence Diagram(s)

sequenceDiagram
    participant Kinde as Kinde (Webhook)
    participant Zapier as Zapier (Catch Raw Hook)
    participant Code as "Zapier Code Action\n(JWT decode)"
    participant Loops as Loops API

    Kinde->>Zapier: POST webhook (payload with JWT)
    Zapier->>Code: Forward raw payload
    Code->>Code: Decode JWT, extract user fields
    Code->>Zapier: Return parsed JSON
    Zapier->>Loops: Create/Upsert contact via API (API key auth)
    Loops-->>Zapier: 200 OK / contact ID
    Zapier-->>Kinde: (optional) acknowledge / log
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I hopped through lines of docs with a twitch and a cheer,
Wired Kinde to Loops so user data appears,
I decoded JWT crumbs and mapped fields just right,
Tested the Zap at dusk and published by night —
A little rabbit hop, integration done clear 🌙🐇

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: new guide - Connect Loops to Kinde' directly and clearly summarizes the main change: adding a new documentation guide for connecting Loops to Kinde via Zapier, which aligns with the 313-line new MDX file being added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 4, 2026

Deploying kinde-docs-preview with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6273ea8
Status: ✅  Deploy successful!
Preview URL: https://42ab368e.kinde-docs-preview.pages.dev
Branch Preview URL: https://tamal-feat-kinde-and-loops-i.kinde-docs-preview.pages.dev

View logs

@tamalchowdhury tamalchowdhury marked this pull request as ready for review February 6, 2026 16:16
@tamalchowdhury tamalchowdhury requested a review from a team as a code owner February 6, 2026 16:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/content/docs/integrate/third-party-tools/kinde-loops.mdx`:
- Around line 108-140: The snippet decodes JWTs but never verifies the
signature, so update the documentation snippet and surrounding text to instruct
callers to validate the webhook JWT before trusting payload fields: add guidance
around the decodeJWT usage to verify the token signature (e.g., using the JWT
library or Kinde's public key/ JWKS) and show where to perform verification
(before using decoded from decodeJWT), reference the decodeJWT function and the
jwt/inputData variable so readers know to replace the simple decoder with a
verification step or call a verify method that checks signature, issuer,
audience, and expiration according to Kinde webhook security guidance.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/content/docs/integrate/third-party-tools/kinde-loops.mdx`:
- Around line 204-207: The instructions ask users to convert users.ndjson to CSV
but give no guidance; update the step that currently reads "Create a new `.csv`
file with the following columns: `First Name`, `Last Name`, `Email`, `User
Group`" (step 7) to include a short, beginner-friendly conversion option:
provide a one-paragraph example approach and a recommended tool—either (a) a
tiny shell/Python snippet that parses users.ndjson and writes those CSV columns
(showing the expected JSON keys to map to First Name/Last Name/Email/User
Group), or (b) a link to a trusted online NDJSON→CSV converter and brief
instructions on selecting/mapping fields—so readers know exactly how to produce
the CSV from users.ndjson before proceeding to the Import CSV step.
- Around line 126-139: The code assumes decoded.data exists before accessing
decoded.data.user, which can throw a TypeError; update the decoding logic
(around decodeJWT and the userData assignment) to guard against missing payloads
by using a safe access pattern (e.g., check decoded && decoded.data or use
optional chaining) so userData becomes decoded?.data?.user || {} (or equivalent)
and ensure the returned fields use that fallback to avoid runtime errors when
decoded.data is undefined.
- Line 41: Remove the incorrect plan requirement text from the Zapier bullet:
delete the phrase "Professional plan or higher required for webhook triggers"
(the Zapier list item currently reads "A [Zapier](https://zapier.com/) account
(Professional plan or higher required for webhook triggers)") and replace it
with a neutral statement such as "A [Zapier](https://zapier.com/) account" so
the Zapier bullet no longer claims webhook triggers require a Professional plan.
- Around line 128-139: The webhook handler currently reads email from
userData.email (the decoded payload) which Kinde's user.created event doesn't
include, so update the logic in the function that builds the returned object
(the block that reads userData and returns
firstName/lastName/email/fullName/userId/orgCode/rawData) to obtain email either
by extracting it from another payload location (e.g.,
decoded.data.user.identities or decoded.data.user_details if present) or, if
absent, call the Kinde Management API to fetch the full user record using
userData.id (or the returned userId) before returning the object; ensure the
returned email field is populated with the fetched/derived value and that any
new network call is handled asynchronously and errors are logged/propagated
rather than silently defaulting to ''.
🧹 Nitpick comments (1)
src/content/docs/integrate/third-party-tools/kinde-loops.mdx (1)

161-161: Minor: Inconsistent UI action verb.

This line uses "Click" while every other UI instruction in the document uses "Select" (e.g., lines 46, 47, 53, 54, 55, etc.). For consistency:

-   - Click **Sign in to Loops**
+   - Select **Sign in to Loops**

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/content/docs/integrate/third-party-tools/kinde-loops.mdx`:
- Around line 283-285: The code block contains a typo: the shell command
"python3 python convert_users_to_csv.py" includes an extra "python" token;
update the code block in
src/content/docs/integrate/third-party-tools/kinde-loops.mdx to use a valid
command such as "python3 convert_users_to_csv.py" (or "python
convert_users_to_csv.py") so the copy-pasted command runs correctly.
🧹 Nitpick comments (1)
src/content/docs/integrate/third-party-tools/kinde-loops.mdx (1)

161-161: Minor terminology inconsistency: "Click" vs "Select".

The rest of the document consistently uses "Select" for UI actions. Consider changing "Click" to "Select" here for consistency.

📝 Proposed fix
-   - Click **Sign in to Loops**
+   - Select **Sign in to Loops**

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/content/docs/integrate/third-party-tools/kinde-loops.mdx`:
- Line 169: Update the documentation entry for the Subscribed default to include
a brief compliance/consent note: mention that setting "Subscribed" (or
`subscribed`) to true auto-opt-ins users to marketing emails and that under
GDPR/CAN-SPAM a legal basis (explicit consent) is typically required, advise
adding copy at signup to capture consent or defaulting `subscribed` to false and
implementing a double opt-in flow, and suggest logging/storing the user's
consent timestamp and source for auditability.
- Around line 128-139: The returned payload mapping currently pulls user fields
from userData (decoded.data.user), but Kinde docs show email may instead be at
decoded.data.email; update the mapping for email (and other user fields as
needed) to defensively check both locations (e.g., prefer
decoded.data.user.email but fallback to decoded.data.email), and apply the same
dual-source fallback for firstName/lastName/fullName/userId/orgCode so the
returned properties (firstName, lastName, email, fullName, userId, orgCode,
rawData) always resolve whether the webhook provides data under
decoded.data.user or directly under decoded.data; ensure trimming and
empty-string fallbacks are preserved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/content/docs/integrate/third-party-tools/kinde-loops.mdx`:
- Line 76: Update the UI label text in the sentence currently reading "Select
**Add event** to select which events you want to trigger this webhook" so it
matches the Mailgun doc's wording by changing "**Add event**" to "**Add
Events**"; locate the exact string "Select **Add event** to select which events
you want to trigger this webhook" in the Kinde Loops integration doc and replace
it with "Select **Add Events** to select which events you want to trigger this
webhook" to ensure consistent wording across docs.
🧹 Nitpick comments (1)
src/content/docs/integrate/third-party-tools/kinde-loops.mdx (1)

20-20: Consider changing complexity to intermediate.

The guide involves JWT token decoding in a Zapier Code action and a Python script for NDJSON-to-CSV conversion. These tasks go beyond beginner-level and are more aligned with intermediate complexity, consistent with the Mailgun guide which is also tagged intermediate.

@tamalchowdhury tamalchowdhury merged commit 7f40f8c into main Feb 13, 2026
6 checks passed
@tamalchowdhury tamalchowdhury deleted the tamal/feat/kinde-and-loops-integration branch February 13, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants