Kajabi has a Public API for connecting Kajabi to other systems. You can add contacts from your own website form. You can give course access to people who paid somewhere else. You can collect purchase data in your own dashboard. If tools like Zapier or Make are not enough, the API gives you more control.
This article explains what the Kajabi API can do and what it cannot do. It is based on the official API reference (version 1.1.0, as of November 2026).
Summary: What the Kajabi API Can Do
The Kajabi Public API is strong in four areas: customer data, access rights (offers), sales data, and event notifications (webhooks).
| Category | What you can do | Main endpoints |
|---|---|---|
| Contacts | List, search, create, update, and delete contacts. Add tags. Grant offers. | /v1/contacts |
| Tags | Get the list and details of tags. Add or remove tags from a contact. | /v1/contact_tags |
| Custom fields | Get the list and details of custom fields. | /v1/custom_fields |
| Contact notes | List, create, update, and delete notes. | /v1/contact_notes |
| Customers | List customers, get details, grant and revoke offers. | /v1/customers |
| Forms | Get forms and submissions. Submit a form. | /v1/forms |
| Products, courses, offers | Get lists and details (read only). | /v1/products /v1/courses /v1/offers |
| Purchases | List and get details. Activate, deactivate, and cancel a subscription. | /v1/purchases |
| Orders and transactions | Get orders, order items, and transactions (charges, refunds, and disputes). | /v1/orders /v1/transactions |
| Payouts | Get the payout history of Kajabi Payments. | Payouts endpoints (for Kajabi Payments users) |
| Sites and pages | Get sites, website pages, landing pages, blog posts, and podcasts. | /v1/sites and others |
| Webhooks | Register notifications for purchases, form submissions, tag changes, and more. | /v1/hooks |
Most write operations are related to contacts. These include contacts, tags, notes, offer grants, and purchase status. Webhooks are also managed through the API. Content such as courses and blog posts is mostly read only. This difference is important when you plan a use case. It is explained in detail later in this article.
Requirement: The Pro Plan or Higher
You need the Pro plan or higher to use the Public API.
According to the official help article, the API is included in the current Pro plan. If you are on a legacy Pro plan (an older Pro subscription), the API is not included by default. You can either upgrade to the current Pro plan or add the Public API add-on for $25 per month.
For webhooks, the help article says they are available on the Growth and Pro plans. However, to create webhooks through the API (/v1/hooks), you need the Public API itself. For this reason, this article assumes the Pro plan for all API-based integrations.

Basic Specifications
Here is the basic information you need first.
| Item | Details |
|---|---|
| Server URL | https://api.kajabi.com |
| Path | All paths start with /v1 |
| Version check | GET https://api.kajabi.com/v1/version |
| Specification | OpenAPI 3.1.1 (the openapi.yaml file can be downloaded) |
| Data format | JSON:API (application/vnd.api+json) |
| Authentication | OAuth 2.0 client credentials (Bearer token) |
| Testing | An official Postman collection is available |
The data format is JSON:API. Requests and responses use the same structure: data, then type, attributes, and relationships. It may look unusual at first. However, all endpoints use the same structure, so it becomes easy after a short time.
List endpoints share these query parameters:
- Pagination:
page[number]andpage[size] - Sorting:
sort=name(usesort=-namefor descending order) - Selecting fields (sparse fields):
fields[contacts]=name,email - Filters: for example,
filter[site_id]=123 - Including related data:
include=offers,tags,customer
Authentication: Create an API Key and Get a Token
Create an API key (client ID and client secret)
- Open the settings in the Kajabi dashboard
In the dashboard, go to “Settings”. Under Account Settings, open “Public API”.
- Click “Create User API Key”
The screen for creating a new API key opens.
- Select a name, a user, and permissions
Enter a name for the key. Use a name that shows the purpose, such as “Inventory sync”. Then select the account user and the permissions (scopes).
- Click “Create” and save the client ID and secret
After the key is created, the client_id and client_secret are shown. Store them in a safe place.
Please note these three points:
- Only Owners and Subowners can create API keys.
- You must select the permissions you need when you create the key. A token from a key with too few permissions is rejected on protected endpoints, even if the token is valid.
- For security, you can delete or rotate a key at any time. When you do this, all access tokens issued with that key become invalid.
Get an access token
You get a token with POST /v1/oauth/token. The recommended method is client_credentials.
curl -X POST https://api.kajabi.com/v1/oauth/token \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"A successful response contains these values:
access_token: the token that you use when you call the APIrefresh_token: a token that you exchange for a new access token when the old one expirestoken_type: alwaysBearerexpires_in: the number of seconds that the access token is valid
After that, add the Bearer token to the Authorization header of each request.
curl https://api.kajabi.com/v1/me \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"There are three ways to exchange credentials for tokens.
| Method | Parameters | Note |
|---|---|---|
| Client credentials | client_id, client_secret, grant_type=client_credentials | Recommended |
| Refresh token | refresh_token, grant_type=refresh_token | Needs an unexpired token from an earlier client credentials grant |
| Username and password | username, password | Not recommended (client credentials are preferred) |
To log out, use POST /v1/oauth/revoke. Send either the access token or the refresh token. Both tokens become invalid.
When you get a 401 or 403 error
If you get 401 Unauthorized or 403 Forbidden after you receive a token, check these three points.
| What to check | Details |
|---|---|
| Key permissions | Did you select the required scopes when you created the key? If not, delete the key and create it again. |
| Activation time | After API access is enabled, it can take up to 10 minutes to become active. |
| Request header | Send the token in the Authorization header as a Bearer token. Do not send it as a query parameter. |
What You Can Do, by Resource
This section explains each resource and the operations it supports.
Contacts
Contacts are the center of customer management in Kajabi.
What you can do
- List and search (
GET /v1/contacts) - Get details (
GET /v1/contacts/{id}) - Create (
POST /v1/contacts) - Update (
PATCH /v1/contacts/{id}) - Delete (
DELETE /v1/contacts/{id})
The main fields are name, email, address (lines 1 and 2, city, state, country, and postal code), phone number, business number, email subscription status (subscribed), external_user_id, and the created and updated times.
When you create a contact, you must set the site relationship to show which site the contact belongs to. If your account has multiple sites, filter[site_id] is also required when you list contacts.
{
"data": {
"type": "contacts",
"attributes": {
"name": "John Doe",
"email": "john.doe@example.com"
},
"relationships": {
"site": {
"data": { "type": "sites", "id": "123" }
}
}
}
}The filters are very rich. This is a strong point of this API. For example, you can find contacts by these conditions:
- Text in the name, email, phone number, or address
- Has or does not have a specific tag (
has_tag_id,has_no_tag_id,has_all_tag_id) - Has or does not have a specific offer (
has_offer_id,has_no_offer_id) - Owns, does not own, or previously owned a specific product (
has_product_idand others) - Submitted or did not submit a specific form
- Registered for an event, or completed, passed, or failed an assessment
- Total net revenue is equal to, above, or below a value
- Created, active, or inactive in the last N days
- Opened, clicked, or bounced on a specific email broadcast
- Hard bouncing, or unsubscribed recently
With these filters, one API call can find, for example, “customers who bought but have not been active for 60 days”. It can also find “people who bought a course but do not have the tag”.
Behavior to know
external_user_id(the user ID in an external system) can be updated only for contacts that already have an offer or a purchase (in other words, customers).- If a contact has an active Kajabi Payments subscription or payment plan, deleting that contact returns a
422error. This was added in the June 2026 update. - Custom fields use handles such as
custom_1andcustom_2. Use/v1/custom_fieldsto see which fields are available.
Tags (Contact Tags)
- Get the list and details of tags (archived tags are not included)
- Add, remove, or replace tags on a contact (POST, DELETE, and PATCH)
In the endpoints I checked, I did not find one that creates tags. You create tags in the dashboard, and you use the API to add or remove them.
Granting and Revoking Offers (Contacts and Customers)
This is probably the most practical function of the Kajabi API. You can grant or revoke offers for a contact or a customer.
| Operation | Method | Description |
|---|---|---|
| Grant | POST | Give an offer |
| Revoke | DELETE | Cancel an offer |
| Replace | PATCH | Replace the current offers with the offers you specify |
| List | GET | See the offers already granted |
When you grant an offer, these steps run automatically:
- The API checks whether the offer was already granted.
- The API looks for an existing customer with the same email address. If there is none, it creates a new customer.
- A welcome email is sent. To stop it, set
send_customer_welcome_email: falseinmetaof the request. - If the offer is a gift, a gift email is sent.
- Configured automations are triggered.
When you revoke an offer, only active offers are affected. All related product memberships are deactivated.
{
"data": [{ "type": "offers", "id": "123" }],
"meta": { "send_customer_welcome_email": false }
}With this function, you can build a system that gives access to Kajabi courses and communities automatically after a signup or a payment in an external system.
Customers
- Get the list and details
- Grant, revoke, and replace offers (the same as for contacts)
The name and email of a customer stay in sync with the linked contact.
Contact Notes
You can list, create, update, and delete notes that are linked to a contact. Only the note text (body) can be updated. The linked contact cannot be changed after the note is created. A list returns 20 items by default and 100 items at most.
For example, you can write sales or support records from an external CRM into Kajabi.
Forms
- Get the list and details of forms
- Get the list and details of form submissions
- Submit a form (
POST /v1/forms/{id}/submit)
To submit a form, only name and email are required. The email address must be valid and deliverable, or the request returns an error.
{
"data": {
"type": "form_submissions",
"attributes": {
"name": "John Doe",
"email": "john.doe@example.com"
}
}
}An important point is that a submission through the API runs the same processing as a submission from the dashboard. The official documentation lists these side effects:
- Check for disposable email addresses and verify that the email is deliverable
- Send a double opt-in email when it is needed
- Subscribe the contact
- Add the tags and grant the offers that are set on the form
- Subscribe the contact to email sequences
- Deliver webhooks and trigger automations
This is useful when you place your own signup form on your website and send the data to a Kajabi form in the background.
Products, Courses, and Offers (Read Only)
- Products: list and details (archived products are not included)
- Courses: list and details. With
include=modules,lessons,lessons.media,offers, you can get modules, lessons, media, and offers in one request. - Offers: list and details. You can get the price, the payment type, the checkout URL, whether it is a subscription, whether it is free, and more.
In the endpoints I checked, there is no endpoint to create or update courses, products, or offers. You cannot use the API to generate course content from an external system.
Purchases
Purchases are the records of offer purchases.
- Get the list and details
- Activate (reactivate) and deactivate a purchase
- Cancel a subscription
There are traps in the behavior:
- Deactivating a purchase does not cancel the subscription.
- Reactivating a purchase does not restart the subscription.
- To stop billing, use the separate cancel subscription endpoint.
“Stopping access” and “stopping billing” are different operations. If you automate cancellations, you may need to call both.
Orders, Order Items, and Transactions
- Orders: list and details
- Order items: the list and details of each product or offer in an order
- Transactions: records of payments linked to real purchases, such as successful charges, refunds, and disputes
The transaction list does not include test transactions, free purchases, failed attempts, and pending transactions. This makes the data easy to use for accounting and sales analysis. For purchases, orders, and transactions, you can filter by customer with filter[customer_id].
A transaction can cover several offers in one charge. For example, this happens when a checkout has several order bumps. To support this, transactions have a purchases relationship (added in June 2026). The older singular offer relationship is deprecated. It returns null for a combined transaction. For new work, use purchases.
Payouts (Kajabi Payments Payouts)
You can get the list and details of Kajabi Payments payouts, which are transfers from Kajabi to your bank account. The details include the related transactions.
As the name shows, these endpoints are for accounts that use Kajabi Payments. Kajabi Payments is not available in every country. Check the availability in the official documentation.
Sites, Pages, Blog Posts, and Podcasts (Read Only)
- Sites: the list and details of the sites you can access
- Website pages: list and details
- Landing pages: list and details
- Blog posts: list and details (title, content, slug, publish date, image, tags, and more)
- Podcasts: list and details
These are also read only. You cannot create or edit pages or blog posts through the API. However, you can get blog posts, so you can show a Kajabi blog on an external website.
Other: Your Own Profile and the Version
GET /v1/me: the profile of the user linked to the API keyGET /v1/version: the API version
You can use these for a connection check.
Webhooks: Receive Events in Real Time
The API is a way to ask Kajabi for data. Webhooks are a way for Kajabi to send a notification to you.
| Public API | Webhooks | |
|---|---|---|
| Role | Get or send data from your program | Notify you immediately when an event happens in Kajabi |
| Direction | Two-way (read and write) | Mainly from Kajabi to an external system |
| Best for | Bulk data access, custom apps, syncing with other systems | Automation that starts from an event, such as a purchase |
Events you can register
| Event | When it is sent | Required scopes |
|---|---|---|
purchase | A customer makes a purchase | view:purchases |
payment_succeeded | A payment is completed | view:transactions |
order_created | A new order is created | view:transactions and view:orders |
form_submission | A form is submitted | view:form_submissions |
tag_added | A tag is added to a contact | view:contacts |
tag_removed | A tag is removed from a contact | view:contacts |
You can register only the events that are allowed by the scopes of your API key.
How to register
Send POST /v1/hooks with the destination URL (target_url) and the event name. If you set resource_id, you receive only the events for that resource, such as a specific tag. If you omit it, you receive all events of that type (a wildcard webhook).
{
"data": {
"type": "hooks",
"attributes": {
"target_url": "https://example.com/webhook",
"event": "tag_added",
"resource_id": "123"
},
"relationships": {
"site": {
"data": { "id": "456", "type": "sites" }
}
}
}
}The notification that reaches your URL is a POST request with this format:
{
"id": "hash_id",
"event": "tag_added",
"payload": []
}id is the ID of the resource that caused the event. event is the event name. payload is the content. To see the shape of the content in advance, use the sample endpoints. There is one for each event, such as GET /v1/hooks/purchase_sample.
For managing webhooks, there are endpoints to list, create, get details, and delete. I did not find an update endpoint. To change a webhook, delete it and create it again.
Limits and Points to Note
This section summarizes the points above and the notes in the official help article.
- Not all data is available through the API. Some data that you see in the dashboard is not in the API reference. If you need a field that is missing, send a feature request through the Kajabi feedback portal.
- Creating and editing content is mostly not possible. Courses, products, offers, blog posts, and landing pages are read only (in the endpoints I checked).
- Features that are not in the list. I did not find endpoints for operating email broadcasts or communities in the published endpoint list.
- Rate limits apply. Kajabi sets limits to protect platform stability. For the current values, see the official documentation or ask Kajabi Support.
- No published IP allowlist. If your environment needs to allow specific IP addresses, ask Support for current guidance.
- No support for custom code. Support can help with possible bugs and questions about API functions. It does not help with writing or debugging your own code.
-
You can work with core data from outside Kajabi: customers, purchases, form submissions, and tags
-
Granting and revoking offers lets you connect external payments and signups with access rights
-
Many filters allow detailed segment searches
-
Webhooks send events in real time
-
An OpenAPI specification and a Postman collection are published
-
The Pro plan or higher is required (a legacy Pro plan needs an extra $25 per month)
-
Content such as courses and blog posts is mostly read only, so the API is not suited to creating or editing it
-
No IP allowlist is published, so strict network environments need to contact Support
-
Support does not cover your own custom code
Example Use Cases
1. Give access to people who paid in an external system When a payment in an external service is completed, create a contact with the API and grant an offer. Kajabi creates the customer automatically. The welcome email and the automations also run.
2. Connect your own signup form to Kajabi Keep your own website design and send the data to the Kajabi form submit endpoint in the background. Tags, email sequences, and offers are processed in one step.
3. Send purchase notifications to Slack or an internal tool
Register a purchase or payment_succeeded webhook. Forward the data you receive to a chat tool or an internal system.
4. Collect sales data in a spreadsheet or a BI tool Get data from the order and transaction endpoints on a schedule, and add it to your own reports. The transaction data does not include test or failed transactions, so it is easy to total.
5. Stop access automatically for cancellations and refunds Deactivate the purchase or revoke the offer to stop access. If needed, also call the cancel subscription endpoint.
How to Get Started
:::steps
- Check your plan
Confirm that you are on the Pro plan or higher (or a legacy Pro plan with the add-on), and that the Public API is active.
- Create an API key
In “Settings”, open “Public API”. Select only the permissions you need and create the key. Only Owners and Subowners can create keys.
- Get a token
Call /v1/oauth/token with your client_id and client_secret to get an access token.
- Check the connection
Call GET /v1/version or GET /v1/me with the Bearer token. You can use a tool such as Postman.
- Get your site ID
Call GET /v1/sites to find the ID of your site. You need it when you list or create contacts.
- Start with a small operation
Start with a contact search, or create a contact with a test email address.
