Manage contacts, tags, offers, products, orders, purchases and forms on a Kajabi site via the Kajabi Public API v1.
Kajabi ships in the w6w first-party pack. It declares 49 actions, 2 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.kajabiKajabi is a creator-commerce platform for courses, memberships and other digital products, and this app lets a workflow manage the contact and commerce side of a Kajabi site. Create, update and look up contacts, tag and untag them, grant or revoke access to an offer, and browse the courses and products those offers unlock.
Money questions go through customers, orders, purchases and transactions: list a customer’s orders and their line items, check payout history for sites on Kajabi Payments, and reactivate, deactivate or fully cancel a purchase’s subscription. Submit a form on a contact’s behalf to trigger the same automations — email sequences, tags, offer grants — that a live signup on a landing page would fire, or use plain contact creation for a bulk import that should stay quiet.
Discovery actions round it out: list a site’s custom fields, tags and forms, and read a form’s own submissions, so a workflow can work with the exact vocabulary a given Kajabi site actually uses.
Three routes to the same 49 actions. The Workflow tab is generated from Kajabi's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
contact-create Create a contact on a site. Kajabi requires the site relationship, so the Site ID is mandatory here.
contact-delete Permanently delete a contact. Kajabi provides no undelete — consider revoking offers or unsubscribing instead if the record may be needed later.
contact-list Search and page through contacts. Covers the common filters directly and forwards any of Kajabi's other documented `filter[…]` parameters.
contact-note-create Add a note to a contact's record — a good way to leave an audit trail a human will see.
contact-note-list List contact notes, normally filtered to one contact. Without a contact filter this returns every note on the site.
contact-note-update Replace a contact note's text. The note stays on the contact it was created against.
contact-offer-grant Give a contact access to one or more offers — the way to fulfil a course, membership or digital product bought outside Kajabi's checkout.
contact-offer-list List the offer ids a contact has been granted. Returns identifiers only — `offer-list` resolves the titles.
contact-offer-revoke Remove a contact's access to one or more offers. Does not cancel any subscription paying for them — use `purchase-cancel-subscription` for that.
contact-tag-add Attach one or more tags to a contact, leaving existing tags in place. Use `contact-tag-replace` only if you intend to discard the contact's other tags.
contact-tag-list List the tag ids attached to a contact. Returns identifiers only — use `contact-get` with `include=tags` if you need the names too.
contact-tag-remove Detach one or more tags from a contact, leaving the contact's other tags intact.
contact-tag-replace Set a contact's tags to exactly this list. Destructive — any tag not listed is removed. Use `contact-tag-add` unless you specifically want replacement.
contact-update Update a contact. Only the fields you fill in are sent, so blank fields are left as they are rather than cleared.
course-list List a site's courses. Read-only — Kajabi's public API publishes no course authoring or learner-progress endpoints.
custom-field-list List a site's custom field definitions — what `custom_1`, `custom_2` and `custom_3` mean on this site's contacts.
customer-list Search and page through customers — the purchasing identity that orders, purchases and transactions are keyed by.
form-submission-list List form submissions, optionally for one form. Sort by `-created_at` to poll for new ones — Kajabi publishes no 'since' filter here.
form-submit Submit a Kajabi form as if a visitor filled it in — firing whatever email sequences, tags and offer grants the creator attached to it. Use `contact-create` instead when you want the record without the automation.
me-get Return the Kajabi user this connection's API key belongs to — name, email and role level.
offer-list List a site's offers — the priced, sellable wrappers around products. `contact-offer-grant` takes the ids this returns.
offer-product-list List the product ids an offer grants access to. Returns identifiers only — use `offer-get` with `include=products` if you want the titles in the same call.
order-item-list List order line items, optionally filtered to one offer or product — the way to ask who bought a particular thing across every order.
order-list List orders, optionally narrowed to one customer, one order number, or to orders that have not been fulfilled yet.
payout-list List Kajabi Payments payouts for a site — money settled to the creator. Only applies to sites using Kajabi Payments.
purchase-cancel-subscription Cancel the subscription behind a purchase at the payment provider (Stripe, PayPal or Kajabi Payments) and deactivate the purchase. This is the complete cancellation — no separate deactivate call is needed. Not reversible through the API.
purchase-deactivate Revoke access to a purchase. WARNING — Kajabi does not cancel the subscription: the customer keeps being billed. Use `purchase-cancel-subscription` if payment should stop.
purchase-list List purchases — the standing access records behind memberships and subscriptions. Feeds the activate, deactivate and cancel actions.
purchase-reactivate Restore access to a deactivated purchase. Does not restart a cancelled subscription — Kajabi reactivates access only. Not every purchase is reactivatable.
site-list List the sites on this Kajabi account. Use the returned id as the Site ID on the other actions — Kajabi requires it once an account has more than one site.
tag-get Fetch one contact tag by id — useful for turning the identifiers returned by `contact-tag-list` back into names.
tag-list List the contact tags defined on a site. Use this to turn a tag name into the id that the tagging and filtering actions require.
transaction-list List individual payments, optionally over a date range — the endpoint for revenue reconciliation.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying Kajabi's real ids.
{
"manifestVersion": "2",
"name": "kajabi-example",
"steps": [
{
"id": "contact-create",
"uses": {
"app": "io.w6w.kajabi",
"action": "contact-create",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"siteId": "<siteId>",
"name": "<name>",
"email": "<email>"
}
}
]
}contact-create contact-get contact-list contact-note-create contact-note-get +44 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for Kajabi, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to Kajabi. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "contact-create",
payload: {
siteId: "<value>",
name: "<value>",
email: "<value>",
// phoneNumber: "<value>",
// businessNumber: "<value>",
// subscribed: "<value>",
// addressLine1: "<value>",
// addressLine2: "<value>",
// addressCity: "<value>",
// addressState: "<value>",
// addressCountry: "<value>",
// addressZip: "<value>",
// customFields: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action contact-create --payload '{"siteId":"<value>","name":"<value>","email":"<value>"}' Give an AI agent Kajabi — without giving it Kajabi's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.kajabi#contact-create",
"input": {
"siteId": "<siteId>",
"name": "<name>",
"email": "<email>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's Kajabi connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
Kajabi's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. Kajabi itself is MIT, and the runtime that executes it is source-available (FSL).
Kajabi declares its own checks, so its health is a property of the app rather than something the host guesses at.
Atlassian Statuspage summary for status.kajabi.com. The verdict tracks the `App Availability` component — Kajabi publishes no component for the public REST API, and its `API` group covers inbound webhooks, which this app does not use. Informational: an outage here explains a failure, but a green board cannot certify the REST API.