Project Status: BETA

  • Server URL https://api.kajabi.com
    • Endpoint paths are prefixed with /v1
    • Version endpoint GET https://api.kajabi.com/v1/version

Documentation

API Keys

  • Your API client_id and client_secret are available on the User API Keys section of the Kajabi Admin Portal.
    • Custom API Keys can be created with specific permissions.
    • Click the "Create User API Key" button, enter a name (e.g. "My project"), select the user and permissions, and click "Create".
    • For security purposes, you may "Delete" or "Rotate" the api credentials at any time; which will invalidate any access tokens granted with the credentials.

Changelog

Release notes...

0.4.0 (April 11, 2025)

New developer site https://developers.kajabi.com
Add resource attribute definitions to docs
Improve docs with comprehensive response examples using a variety of request parameters
Add checkout url to offer resource
Add endpoints for forms, including form submission
Contacts related offers are linked by url vs listed by id
Add publishing_option to module/lesson public api
Add internal_title and payment info attributes to offer serializer
Add refresh_token to oauth/token response
Add transactions endpoints
Add lessons.media relationship for courses

0.3.0 (March 19, 2025)

Add oauth revoke endpoint
Improve docs for oauth token credential grant
Add contacts filter params: search, has_product_id, has_tag_id, has_offer_id
Add customers endpoints
Add courses endpoints
Add example responses to docs for page and filter parameters
Improve docs for success responses
Add forbidden error response examples
Improve docs for granting and revoking offers

0.2.0 (October 25, 2024)

Credential exchange using Kajabi account api key/secret
Add contacts offers relation endpoints to grant/revoke offers
Add contacts relationship to offers
Add products relationship to offers
Add products endpoints
Add offers endpoints

0.1.3 (October 21, 2024)

Add contact tag endpoints
Add contacts tag relation endpoints to add/remove tags
Document /contacts/{id}?include= parameter with tags example```

0.1.2 (October 11, 2024)

Add /api/v1/custom_fields endpoint
Add clarify filters for contacts in the openapi spec

0.1.1 (October 3, 2024)

Add sorting to contacts
Add sparse fields to contacts
Add filters to contacts list endpoint

0.1.0 (July 22, 2024)

Add contacts endpoints
Add sites endpoints
Add me endpoint for current user
Add version endpoint
Add oauth/token endpoint to authenticate with username/password

Authentication

/oauth/token

Request access_token and refresh_token

There are three ways to exchange parameters for tokens

  1. Provide client credentials client_id and client_secret
  2. Provide a refresh_token
  3. Provide username and password (client credentials is preferred)

Using grant_type=client_credentials

Only include params: client_id, client_secret, and grant_type.

  • The grant_type param value must be: client_credentials

Using grant_type=refresh_token

Only include params: refresh_token and grant_type.

  • The grant_type param value must be: refresh_token
  • The refresh_token must be a unexpired JWT token, from a prior client credential token grant.

Using username and password

Only include params: username and password.

Response

A successful response will provide access_token and refresh_token values.

  • Use the access_token in your Authorization header as a "Bearer" token to make authenticated requests to the API. E.g. GET https://api.kajabi.com/v1/me
  • Store the refresh_token to exchange for a new access_token when it expires.
  • Tokens may be invalidated using the v1/oauth/revoke endpoint to "log out".

Attributes

  • access_token (string) - The access token for the API session
  • refresh_token (string) - The refresh token for the API session
  • token_type (string) - The type of token, always Bearer
  • expires_in (integer) - The number of seconds the access token will be valid for
Request Body schema: application/x-www-form-urlencoded
username
string
password
string
client_id
string
client_secret
string
grant_type
string
scope
string
refresh_token
string

Responses

Response samples

Content type
application/json
{
  • "access_token": "string",
  • "refresh_token": "string",
  • "token_type": "string",
  • "expires_in": 0
}

/oauth/revoke

Revoke an access_token and refresh_token

Either token may be provided to "log out" of the API session. Both tokens we be invalidated.

  • Only include param: token with your access_token or refresh_token
  • Requires an Authorization header as Bearer access_token to authenticate the request.

Response

  • A successful response will have an empty body
  • An error response will include a JSON body with error details.
Authorizations:
Bearer
Request Body schema: application/x-www-form-urlencoded
token
required
string

Responses

Contact Tags

/contact_tags

Tags (not archived) for a site

Contact Tag Attributes

  • name (string) - The name of the contact tag

Pagination

Use the page[number] and page[size] query parameters to paginate results:

Get first page of 10 items

  • GET /v1/contact_tags?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/contact_tags?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://api.kajabi.com/v1/contact_tags?page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/contact_tags?page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/contact_tags?page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/contact_tags?page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/contact_tags?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Filter by Site ID

Use the filter[site_id] parameter to get contact tags for a specific site:

Get contact tags for site with ID 123

  • GET /v1/contact_tags?filter[site_id]=123

Response will only include contact tags for that site

{
  "data": [{
    "id": "456",
    "type": "contact_tags",
    "attributes": {
      "name": "Source"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filter by Name Contains

Use the filter[name_cont] parameter to find contact tags where the name contains specific text:

Get contact tags with names containing "vip"

  • GET /v1/contact_tags?filter[name_cont]=vip

Response will include contact tags with matching names

{
  "data": [{
    "id": "456",
    "type": "contact_tags",
    "attributes": {
      "name": "VIP Customer"
    }
  }]
}

Using Multiple Parameters Together

You can combine pagination, sorting, sparse fields and filtering in a single request:

Get page 2 of contact tags for site 123, sorted by name descending

  • GET /v1/contact_tags?page[number]=2&page[size]=10&sort=-name&filter[site_id]=123

Response will include only requested fields, sorted and paginated

{
  "data": [{
    "id": "456",
    "type": "contact_tags",
    "attributes": {
      "name": "Webinar Attendee"
    }
  }, {
    "id": "789",
    "type": "contact_tags",
    "attributes": {
      "name": "VIP Customer"
    }
  }],
  "links": {
    "self": "https://api.kajabi.com/v1/contact_tags?page[number]=2&page[size]=10&sort=-name&fields[contact_tags]=name,handle&filter[site_id]=123",
    "first": "https://api.kajabi.com/v1/contact_tags?page[number]=1&page[size]=10&sort=-name&fields[contact_tags]=name,handle&filter[site_id]=123",
    "prev": "https://api.kajabi.com/v1/contact_tags?page[number]=1&page[size]=10&sort=-name&fields[contact_tags]=name,handle&filter[site_id]=123",
    "next": "https://api.kajabi.com/v1/contact_tags?page[number]=3&page[size]=10&sort=-name&fields[contact_tags]=name,handle&filter[site_id]=123",
    "last": "https://api.kajabi.com/v1/contact_tags?page[number]=5&page[size]=10&sort=-name&fields[contact_tags]=name,handle&filter[site_id]=123"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: name, email, for descending order use '-' e.g. &sort=-name

page[number]
number
page[size]
number

Number of documents

fields[contact_tags]
string

Partial attributes as specified, e.g. fields[contact_tags]=name

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[name_cont]
string

Filter by name contains, for example ?filter[name_cont]=vip

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contact_tags/{id}

Contact Tag Attributes

  • name (string) - The name of the contact tag

Contact Tag Relationships

The contact tag belongs to a site

Authorizations:
Bearer
path Parameters
id
required
string

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

Contacts

/contacts

Create a contact for a site.

Contact attributes

  • New contact does not support external_user_id attribute.
  • See custom_fields endpoint to discover attributes for using custom fields attributes.

Create a contact

Request body must include a site relationship. Example request body:

{
  "data": {
    "type": "contacts",
    "attributes": {
      "name": "John Doe",
      "email": "[email protected]"
    },
    "relationships": {
      "site": {
        "data": {
          "type": "sites",
          "id": "123"
        }
      }
    }
  }
}

Response will include the newly created contact resource.

{
  "data": {
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "John Doe",
      "email": "[email protected]",
      "address_line_1": null,
      "address_line_2": null,
      "address_city": null,
      "address_country": null,
      "address_state": null,
      "address_zip": null,
      "phone_number": null,
      "business_number": null,
      "subscribed": false,
      "external_user_id": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }
}
Authorizations:
Bearer
Request Body schema: application/vnd.api+json
required
object

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

/contacts

List of contacts, we recommended filtering by site.

Filtering

Use the filter[site_id] parameter to filter contacts by site:

Get contacts for site with ID 123

  • GET /v1/contacts?filter[site_id]=123

Response will include only contacts for the specified site

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Search Filter

Use the filter[search] parameter along with filter[site_id] to search contacts by name or email:

Search for contacts containing "smith" in site with ID 123

  • GET /v1/contacts?filter[site_id]=123&filter[search]=smith

Response will include only matching contacts for the specified site

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Use the use_indexed_data parameter along with filter[site_id] and filter[search] to search contacts using an alternative search algorithm:

Search for contacts containing "smith" in site with ID 123 using indexed data

  • GET /v1/contacts?filter[site_id]=123&filter[search]=smith&use_indexed_data=true

Response will include matching contacts using the indexed search algorithm

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Using Pagination with Site Filter

Use the filter[site_id] parameter along with pagination parameters page[number] and page[size] to get paginated results for a specific site:

Get page 2 of contacts from site with ID 123, with 10 items per page

  • GET /v1/contacts?filter[site_id]=123&page[number]=2&page[size]=10

Response will include paginated contacts for the specified site along with pagination metadata

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }],
  "links": {
    "self": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Using Sort with Site Filter

  • The default Sorting is by created_at in descending order (newest first)

Sorting by created_at in ascending order (oldest first)

  • GET /v1/contacts?filter[site_id]=123&sort=created_at

Use the sort parameter along with filter[site_id] to get sorted results for a specific site:

Get contacts from site with ID 123, sorted by name in ascending order

  • GET /v1/contacts?filter[site_id]=123&sort=name

Get contacts from site with ID 123, sorted by email in descending order

  • GET /v1/contacts?filter[site_id]=123&sort=-email

Response will include sorted contacts for the specified site

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Using Sparse Fields with Site Filter

Use the fields[contacts] parameter along with filter[site_id] to get specific fields for contacts in a site:

Get only name and email fields for contacts from site with ID 123

  • GET /v1/contacts?filter[site_id]=123&fields[contacts]=name,email

Response will include only requested fields for contacts in the specified site

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filtering by Site and Offer

Use the filter[site_id] parameter along with filter[has_offer_id] to get contacts who have been granted a specific offer

Get contacts from site with ID 123 who have been granted offer with ID 789

  • GET /v1/contacts?filter[site_id]=123&filter[has_offer_id]=789

Response will include only contacts from the specified site who have been granted the offer

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filtering by Site and Product

Use the filter[site_id] parameter along with filter[has_product_id] to get contacts who have purchased a specific product

Get contacts from site with ID 123 who have purchased product with ID 789

  • GET /v1/contacts?filter[site_id]=123&filter[has_product_id]=789

Response will include only contacts from the specified site who have purchased the product

{
  "data": [{
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filtering by Site and Tag

Use the filter[site_id] parameter along with filter[has_tag_id] to get contacts who have a specific tag

Get contacts from site with ID 123 who have tag with ID 456

  • GET /v1/contacts?filter[site_id]=123&filter[has_tag_id]=456

Response will include only contacts from the specified site who have the tag

{
  "data": [{
    "id": "789",
    "type": "contacts",
    "attributes": {
      "name": "Bob Jones",
      "email": "[email protected]",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Using Multiple Parameters Together

You can combine multiple parameters to filter, search, paginate and format the response:

Get paginated contacts from site 123 with tag 456, searching for "smith", using indexed data and sparse fields

  • GET /v1/contacts?filter[site_id]=123&filter[has_tag_id]=456&filter[search]=smith&use_indexed_data=true&page[number]=1&page[size]=10&fields[contacts]=name,email

Response will include paginated contacts matching all filters with only requested fields

{
  "data": [{
    "id": "789",
    "type": "contacts",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]"
    }
  }],
  "links": {
    "self": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&filter[has_tag_id]=456&filter[search]=smith&use_indexed_data=true&page[number]=1&page[size]=10&fields[contacts]=name,email",
    "first": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&filter[has_tag_id]=456&filter[search]=smith&use_indexed_data=true&page[number]=1&page[size]=10&fields[contacts]=name,email",
    "prev": null,
    "next": null,
    "last": "https://api.kajabi.com/v1/contacts?filter[site_id]=123&filter[has_tag_id]=456&filter[search]=smith&use_indexed_data=true&page[number]=1&page[size]=10&fields[contacts]=name,email"
  },
  "meta": {
    "total_pages": 1,
    "total_count": 1,
    "current_page": 1
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: name, email, created_at, for descending order use '-' e.g. &sort=-name

page[number]
number
page[size]
number

Number of documents

fields[contacts]
string

Sparse fields, use: name, email for example ?fields[contacts]=name,email

filter[site_id]
string

It is recommended to always filter by site_id, for example ?filter[site_id]=111. This param is required when using the following params: search, has_offer_id, has_product_id, has_tag_id. Also, it is required for use with use_indexed_data param

use_indexed_data
string

Alternative algorithm for searching/filtering (in some cases performs faster), for example ?use_indexed_data=true

filter[external_user_id_cont]
string

contains filter, for example ?filter[external_user_id_cont]=123

filter[external_user_id_eq]
string

equals filter, for example ?filter[external_user_id_eq]=234

filter[external_user_id_start]
string

starts with filter, for example ?filter[external_user_id_start]=345

filter[email_cont]
string

deprecated, use filter[search]

filter[email_eq]
string

deprecated, use filter[search]

filter[email_start]
string

deprecated use filter[search]

filter[name_cont]
string

deprecated, use filter[search]

filter[name_eq]
string

deprecated, use filter[search]

filter[name_start]
string

deprecated, use filter[search]

filter[search]
string

Filter with fuzzy search of name/email, for example ?filter[search]=alexa

filter[has_offer_id]
string

Filter based on granted offer, for example ?filter[has_offer_id]=111

filter[has_product_id]
string

Filter based on product purchase, for example ?filter[has_product_id]=222

filter[has_tag_id]
string

Filter based on product purchase, for example ?filter[has_tag_id]=333

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}

Show details for a contact

Contact Attributes

  • name (string) - The name of the contact
  • email (string) - The email of the contact, must be a valid and deliverable email address
  • address_line_1 (string) - The first line of the contact's address
  • address_line_2 (string) - The second line of the contact's address
  • address_city (string) - The city of the contact's address
  • address_country (string) - The country of the contact's address
  • address_state (string) - The state of the contact's address
  • address_zip (string) - The zip code of the contact's address
  • phone_number (string) - The phone number of the contact
  • business_number (string) - The business phone number of the contact
  • subscribed (boolean) - Whether the contact has opted in to receive marketing communications from the site
  • external_user_id (string) - The external user ID of the contact/customer; this field is only updatable if the contact has been granted an offer or made a purchase
  • created_at (string) - The date and time the contact was created
  • updated_at (string) - The date and time the contact was last updated

Including Relationships

Use the include parameter to include related resources in the response:

  • GET /v1/contacts/123?include=offers,tags,customer

Response will include the related contact offers, tags and customer resources

{
  "data": {
    "id": "123",
    "type": "contacts",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]",
      "address_line_1": null,
      "address_line_2": null,
      "address_city": null,
      "address_country": null,
      "address_state": null,
      "address_zip": null,
      "phone_number": null,
      "business_number": null,
      "subscribed": false,
      "external_user_id": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "links": {
      "customer": "https://api.kajabi.com/v1/customers/321"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      },
      "offers": {
        "links": {
          "data": [
            { "id": "456", "type": "offers" }
          ],
          "self": "https://api.kajabi.com/v1/contacts/123/relationships/offers"
        }
      },
      "tags": {
        "data": [
          { "id": "789", "type": "contact_tags" }
        ],
        "links": {
          "self": "https://api.kajabi.com/v1/contacts/123/relationships/tags"
        }
      },
      "customer": {
        "data": {
          "id": "321",
          "type": "customers"
        }
      }
    }
  },
  "included": [
    {
      "id": "456",
      "type": "offers",
      "attributes": {
        "name": "Offer 1",
        "description": "Offer 1 description",
        "internal_title": "Offer 1",
        "price_in_cents": 0,
        "payment_type": "free",
        "token": "offer_123",
        "payment_method": "none",
        "price_description": "Free",
        "checkout_url": "https://mywebsite.com/offers/456",
        "recurring_offer": false,
        "subscription": false,
        "one_time": true,
        "single": false,
        "free": true
      }
    },
    {
      "id": "789",
      "type": "contact_tags",
      "attributes": {
        "name": "Tag Name"
      }
    },
    {
      "id": "321",
      "type": "customers",
      "attributes": {
        "name": "John Smith",
        "email": "[email protected]",
        "avatar": null,
        "external_user_id": "cust_123",
        "public_bio": null,
        "public_location": null,
        "public_website": null,
        "socials": null,
        "net_revenue": "0.0",
        "sign_in_count": 0,
        "last_request_at": null,
        "bounced_at": null,
        "created_at": "2024-01-15T10:30:00Z",
        "updated_at": "2024-01-15T10:30:00Z"
      }
    }
  ]
}

Sparse Fields

Use the fields[contacts] parameter to get specific fields for a contact:

  • GET /v1/contacts/123?fields[contacts]=name,email

Response will include only requested fields for the contact

{
  "data": {
    "id": "123",
    "type": "contacts",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]"
    }
  }
}

Using Multiple Parameters Together

You can combine multiple parameters to include related resources and get specific fields for a contact:

  • GET /v1/contacts/123?include=customer&fields[contacts]=email&fields[customers]=net_revenue

Response will include the related customer resource and only requested fields for the contact and customer

{
  "data": {
    "id": "123",
    "type": "contacts",
    "attributes": {
      "email": "[email protected]"
    },
    "relationships": {}
  },
  "included": [
    {
      "id": "321",
      "type": "customers",
      "attributes": {
        "net_revenue": "0.0"
      }
    }
  ]
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
include
string

with ?include=offers,tags,customer the response will include the related contact offers, tags and customer resources

fields[contacts]
string

Sparse fields, use: name, email for example ?fields[contacts]=name,email

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

/contacts/{id}

Contact attributes

  • A contact with a related customer resource does support external_user_id attribute.
  • See custom_fields endpoint to discover attributes for using custom fields attributes.

Update a contact

Example request body:

{
  "data": {
    "type": "contacts",
    "id": "456",
    "attributes": {
      "phone_number": "12134567890"
    }
  }
}

Response will include the update contact resource.

{
  "data": {
    "id": "456",
    "type": "contacts",
    "attributes": {
      "name": "John Doe",
      "email": "[email protected]",
      "address_line_1": null,
      "address_line_2": null,
      "address_city": null,
      "address_country": null,
      "address_state": null,
      "address_zip": null,
      "phone_number": "12134567890",
      "business_number": null,
      "subscribed": false,
      "external_user_id": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }
}
Authorizations:
Bearer
path Parameters
id
required
string
Request Body schema: application/vnd.api+json
required
object
object

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "relationships": {
    }
}

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

/contacts/{id}

Authorizations:
Bearer
path Parameters
id
required
string

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": { }
}

/contacts/{id}/relationships/offers

Get the contact's relationship to offers (granted).

Response is a list of resource identifiers

{
  "data": [
    { "type": "offers", "id": "123" },
    { "type": "offers", "id": "456" }
  ]
}

The related tag resources are available using the GET api/v1/offers endpoint. The resource identifier includes the offer id and type. Example URLs: /api/v1/offers/123, /api/v1/offers/456

Authorizations:
Bearer
path Parameters
contact_id
required
string

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}/relationships/offers

Grant offer(s) to a contact

Create an offer grant for a contact which results in creating a new customer record for your contact.

In the request body inlcude offer resource identifier(s), id: OFFER_ID, type: "offers".

To skip sending a welcome email to the customer include a meta object in the request body.

{ "data": [{"type": "offers", "id": "123"}], "meta": {"send_customer_welcome_email": false}}

The meta attribute send_customer_welcome_email as false will prevent sending the welcome email.

(The default behavior is to send the welcome email.)

Response

  • A successful response body will list the offers related to the contact
  • An error response will include a JSON body with error details.

Behaviors and side effects

  • Checks if the contact was already granted the offer
  • Checks for existing customerby email
    • If no existing customer, generates a new customer record with contact details
  • May send a welcome email to the customer
  • May send a gift granted email if this is a gift offer
  • Triggers automations if configured
Authorizations:
Bearer
path Parameters
contact_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifier)
object

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "meta": {
    }
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}/relationships/offers

Revoke offer grant(s) for a contact

Revoke offer grant(s) using a list of resource identifiers In the request body inlcude offer resource identifier(s), id: OFFER_ID, type: "offers".

{ "data": [{"type": "offers", "id": "123"}] }

Response

  • A successful response body will list the offers related to the contact
  • An error response will include a JSON body with error details.

Behaviors and side effects

  • Only affects active offers
  • Handles both offer purchases and offer grants
  • Deactivates all associated product memberships
Authorizations:
Bearer
path Parameters
contact_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifier)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}/relationships/offers

Replace offer grant(s) for a contact

Replace offer grants (grants and revokes offers to/from contact) using a list of resource identifiers In the request body inlcude offer resource identifier(s), id: OFFER_ID, type: "offers".

{ "data": [{"type": "offers", "id": "456"}, {"type": "offers", "id": "789"}] }

Response

  • A successful response body will list the offers related to the contact
  • An error response will include a JSON body with error details.
Authorizations:
Bearer
path Parameters
contact_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifier)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}/relationships/tags

Get the contact's relationship to tags, response is a list of resource identifiers

Response is a list of resource identifiers

{
  "data": [
    { "type": "contact_tags", "id": "123" },
    { "type": "contact_tags", "id": "456" }
  ]
}

The related tag resources are available using the GET api/v1/contact_tags endpoint. The resource identifier includes the contact tag id and type. Example URLs: /api/v1/contact_tags/123, /api/v1/contact_tags/456

Authorizations:
Bearer
path Parameters
contact_id
required
string

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}/relationships/tags

Add tag relationships to contact resource using a list of resource identifiers

Request body includes a list of resource identifiers, id: CONTACT_TAG_ID, type: "contact_tags".

{ "data": [{ "type": "contact_tags", "id": "456" }] }

The response body will include the updated list of tag relationships.

Example response body:

{ "data": [{ "type": "contact_tags", "id": "123" }, { "type": "contact_tags", "id": "456" }] }
Authorizations:
Bearer
path Parameters
contact_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifier)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}/relationships/tags

Remove tag relationships to contact resource using a list of resource identifiers.

Request body includes a list of resource identifiers, id: CONTACT_TAG_ID, type: "contact_tags".

{ "data": [{ "type": "contact_tags", "id": "456" }] }

The response body will include the updated list of tag relationships.

Example response body:

{ "data": [{ "type": "contact_tags", "id": "123" }] }
Authorizations:
Bearer
path Parameters
contact_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifier)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/contacts/{id}/relationships/tags

Replace tag relationships to contact resource using a list of resource identifiers.

Request body includes a list of resource identifiers, id: CONTACT_TAG_ID, type: "contact_tags".

{ "data": [{ "type": "contact_tags", "id": "123" }, { "type": "contact_tags", "id": "456" }] }

The response body will include the updated list of tag relationships.

{ "data": [{ "type": "contact_tags", "id": "123" }, { "type": "contact_tags", "id": "456" }] }
Authorizations:
Bearer
path Parameters
contact_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifier)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

Products

/courses

List of courses that can be offered to a contact or purchased

Pagination

Use the page[number] and page[size] query parameters to paginate results:

Get first page of 10 items

  • GET /v1/courses?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/courses?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://api.kajabi.com/v1/courses?page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/courses?page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/courses?page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/courses?page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/courses?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Sorting

Use the sort parameter to sort the results:

Sort by title in ascending order

  • GET /v1/courses?sort=title

Sort by title in descending order

  • GET /v1/courses?sort=-title

Response will include courses sorted by the specified field

{
  "data": [
    {
      "id": "123",
      "type": "courses",
      "attributes": {
        "title": "Advanced Marketing",
        "description": "Master level marketing course",
        "status": "active"
      }
    },
    {
      "id": "456",
      "type": "courses",
      "attributes": {
        "title": "Marketing Basics",
        "description": "Introduction to marketing",
        "status": "active"
      }
    }
  ]
}

Sparse Fields

Use the fields parameter to request only specific attributes:

Only return title and thumbnail_url attributes

  • GET /v1/courses?fields[courses]=title,thumbnail_url

Response will only include requested fields

{
  "data": [{
    "id": "123",
    "type": "courses",
    "attributes": {
      "title": "Marketing Fundamentals",
      "thumbnail_url": "https://example.com/thumbnail.jpg"
    }
  }]
}

Filter by Site ID

Use the filter[site_id] parameter to get courses for a specific site:

Get courses for site with ID 123

  • GET /v1/courses?filter[site_id]=123

Response will only include courses for that site

{
  "data": [{
    "id": "456",
    "type": "courses",
    "attributes": {
      "title": "Marketing Fundamentals",
      "description": "Introduction to marketing concepts",
      "status": "active"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filter by Title Contains

Use the filter[title_cont] parameter to find courses where the title contains specific text:

Get courses with titles containing "marketing"

  • GET /v1/courses?filter[title_cont]=marketing

Response will include courses with matching titles

{
  "data": [{
    "id": "456",
    "type": "courses",
    "attributes": {
      "title": "Marketing Fundamentals",
      "description": "Introduction to marketing concepts",
      "status": "active"
    }
  }]
}

Filter by Description Contains

Use the filter[description_cont] parameter to find courses where the description contains specific text:

Get courses with descriptions containing "marketing"

  • GET /v1/courses?filter[description_cont]=marketing

Response will include courses with matching descriptions

{
  "data": [{
    "id": "456",
    "type": "courses",
    "attributes": {
      "title": "Marketing Fundamentals",
      "description": "Introduction to marketing concepts and strategies",
      "status": "active"
    }
  }]
}

Using Multiple Parameters Together

You can combine pagination, sparse fields, filtering and sorting in a single request:

Get first page of 10 courses for site 123, sorted by title, showing only specific fields

  • GET /v1/courses?page[number]=1&page[size]=10&filter[site_id]=123&sort=title&fields[courses]=title,thumbnail_url

Response will include pagination, sorted filtered results with requested fields

{
  "data": [{
    "id": "456",
    "type": "courses",
    "attributes": {
      "title": "Advanced Marketing",
      "thumbnail_url": "https://example.com/thumbnail1.jpg"
    }
  },
  {
    "id": "789",
    "type": "courses",
    "attributes": {
      "title": "Marketing Basics",
      "thumbnail_url": "https://example.com/thumbnail2.jpg"
    }
  }],
  "links": {
    "self": "https://api.kajabi.com/v1/courses?page[number]=1&page[size]=10&filter[site_id]=123&sort=title&fields[courses]=title,thumbnail_url",
    "first": "https://api.kajabi.com/v1/courses?page[number]=1&page[size]=10&filter[site_id]=123&sort=title&fields[courses]=title,thumbnail_url",
    "next": "https://api.kajabi.com/v1/courses?page[number]=2&page[size]=10&filter[site_id]=123&sort=title&fields[courses]=title,thumbnail_url",
    "last": "https://api.kajabi.com/v1/courses?page[number]=3&page[size]=10&filter[site_id]=123&sort=title&fields[courses]=title,thumbnail_url"
  },
  "meta": {
    "total_pages": 3,
    "total_count": 25,
    "current_page": 1
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: title, for descending order use '-' e.g. &sort=-title

page[number]
number
page[size]
number

Number of documents

fields[courses]
string

Partial attributes as specified, e.g. fields[courses]=title,thumbnail_url

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[title_cont]
string

Filter by title contains, for example ?filter[title_cont]=marketing

filter[description_cont]
string

Filter by description contains, for example ?filter[description_cont]=marketing

filter[publish_status_eq]
string

Filter by publish status, for example ?filter[publish_status_eq]=published

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/courses/{id}

Details of a course that can be offered to a contact or purchased

Course Attributes

  • created_at (string) - The date and time the course was created
  • title (string) - The title of the course
  • description (string) - The description of the course
  • thumbnail_url (string) - The URL of the course thumbnail

Including Relationships

Use the include query parameter to load related resources:

  • GET /v1/courses/123?include=modules,lessons,lessons.media,offers

Response will include the requested related resources (Note: The responses listed within the "included" array will also include the relationships for each resource)

{
  "data": {
    "id": "123",
    "type": "courses",
    "attributes": {
      "created_at": "2024-08-06T05:30:38.669Z",
      "title": "Advanced Marketing",
      "description": "Master level marketing course",
      "thumbnail_url": "https://example.com/thumbnail.jpg"
    },
    "relationships": {
      "modules": {
        "data": [{
          "id": "456",
          "type": "modules"
        }]
      },
      "lessons": {
        "data": [{
          "id": "789",
          "type": "lessons"
        }]
      },
      "offers": {
        "data": [{
          "id": "101",
          "type": "offers"
        }]
      }
    },
    "included": [{
      "id": "456",
      "type": "modules",
      "attributes": {
        "title": "Marketing Fundamentals",
        "description": "Introduction to marketing concepts",
        "position": 1,
        "poster_image_url": "https://example.com/poster.jpg",
        "publishing_option": "published"
      }
    },
    {
      "id": "789",
      "type": "lessons",
      "attributes": {
        "title": "Marketing Basics",
        "position": 1,
        "status": "published",
        "publishing_option": "published"
      }
    },
    {
      "id": "202",
      "type": "media",
      "attributes": {
        "duration_in_minutes": 1,
      }
    },
    {
      "id": "101",
      "type": "offers",
      "attributes": {
        "price": 100.0,
        "currency": "USD",
        "status": "active"
      }
    }]
  }
}

Module attributes

Modules are part of Kajabi's course structure: courses contain modules and modules contain lessons

  • title (string) - A required field that represents the name or heading of the module. This is used to:
    • Identify and display the module in the course outline
    • Organize related lessons/content
    • Provide navigation structure in the course
    • The title must be unique within a course.
  • description (string) - An optional text field that provides additional information about the module's content. This can be used to:
    • Give students an overview of what they'll learn
    • Explain the module's objectives
    • Provide context for the contained lessons
    • Help students understand the module's purpose in the course structure
  • position (integer) - A numeric field that determines the order of modules within a course. This:
    • Used for sorting
    • Allows modules to be reordered
    • Maintains the course's logical progression
    • Is used for navigation between modules
    • Starts at position 1 for the first module
  • poster_image_url (string) - A URL to an image that represents the module visually. This:
    • Can be uploaded through the Kajabi admin interface
    • Is used as a thumbnail/preview image
    • Helps with visual organization of the course
  • publishing_option (string) - Controls the visibility and availability of the module. Options include:
    • published - Module is visible and available to students
    • draft - Module is hidden and not yet available
    • Can be used with drip settings for timed release
    • Affects the visibility of contained lessons
    • Syncs with the course's overall publishing status

Lesson attributes

Lessons can include various types of content: text content (body), videos, audio, quizzes, assessments, and downloads.

  • title (string) - A required field that represents the name or heading of the lesson. This:
    • Must be present
    • Has a maximum length of 200 characters
    • Is used for display and navigation
    • Can be searched (using pg_search)
    • Is used in course outlines and navigation
  • position (integer) - A numeric field that determines the order of lessons within a module (category). This:
    • Usedfor sorting (ranks :sort, column: :position)
    • Is scoped within each module
    • Allows lessons to be reordered
    • Maintains the logical flow of content
    • Is used for navigation between lessons
  • status (string) - An field that tracks the lesson's processing state:
    • ready - Default state, lesson is ready for use
    • duplicating - Lesson is being copied
    • failed - An error occurred during processing
    • This is particularly relevant for lessons with media content or during duplication.
  • publishing_option (string) - Controls the visibility and availability of the lesson. Options include:
    • draft - Lesson is hidden and not yet available to students
    • published - Lesson is visible and available (sets publish_at to current time)
    • drip - Lesson becomes available after a specified number of days
    • locked - Lesson is locked until certain conditions are met (e.g., completing previous lessons)

Media attributes

  • duration_in_minutes (float) - The length of a media file (typically video or audio) in minutes.

Sparse Fields

Use the fields parameter to request only specific attributes:

Only return title and thumbnail_url attributes

  • GET /v1/courses/123?fields[courses]=title,thumbnail_url

Response will only include requested fields

{
  "data": {
    "id": "123",
    "type": "courses",
    "attributes": {
      "title": "Marketing Fundamentals",
      "thumbnail_url": "https://example.com/thumbnail.jpg"
    }
  }
}

Using Multiple Parameters Together

You can combine sparse fields and include in a single request:

Get course details with modules and lessons, showing only specific fields

  • GET /v1/courses/123?include=modules,lessons,lessons.media&fields[courses]=title,thumbnail_url&fields[modules]=title&fields[lessons]=title&fields[media]=duration_in_minutes

Response will include related resources with requested fields

{
  "data": {
    "id": "123",
    "type": "courses",
    "attributes": {
      "title": "Marketing Fundamentals",
      "thumbnail_url": "https://example.com/thumbnail.jpg"
    },
    "relationships": {}
  },
  "included": [{
    "id": "456",
    "type": "modules",
    "attributes": {
      "title": "Marketing Basics"
    }
  },
  {
    "id": "789",
    "type": "lessons",
    "attributes": {
      "title": "Marketing Strategies"
    }
  },
  {
    "id": "101",
    "type": "media",
    "attributes": {
      "duration_in_minutes": 30
    }
  }]
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
include
string

Load the related resources, for example ?include=modules,lessons,lessons.media

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    },
  • "included": [
    ]
}

/products

List of products (not archived) that can be granted to a contact

Pagination

Use page[number] and page[size] parameters to paginate results:

Get first page of 10 items

  • GET /v1/products?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/products?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://api.kajabi.com/v1/products?page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/products?page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/products?page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/products?page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/products?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Sorting

Use the sort parameter to sort the results:

Sort by title in ascending order

  • GET /v1/products?sort=title

Sort by title in descending order

  • GET /v1/products?sort=-title

Response will include products sorted by the specified field

{
  "data": [
    {
      "id": "123",
      "type": "products",
      "attributes": {
        "title": "Advanced Course",
        "description": "In-depth training",
        "status": "active"
      }
    },
    {
      "id": "456",
      "type": "products",
      "attributes": {
        "title": "Beginner Course",
        "description": "Introduction to basics",
        "status": "active"
      }
    }
  ]
}

Sparse Fields

Use the fields[products] parameter to request only specific attributes:

Get only title and publish_status fields

  • GET /v1/products?fields[products]=title,publish_status

Response will only include the requested fields

{
  "data": [
    {
      "id": "123",
      "type": "products",
      "attributes": {
        "title": "Advanced Course",
        "publish_status": "published"
      }
    },
    {
      "id": "456",
      "type": "products",
      "attributes": {
        "title": "Beginner Course",
        "publish_status": "draft"
      }
    }
  ]
}

Filter by Site ID

Use the filter[site_id] parameter to get products for a specific site:

Get products for site with ID 123

  • GET /v1/products?filter[site_id]=123

Response will only include products for that site

{
  "data": [
    {
      "id": "456",
      "type": "products",
      "attributes": {
        "title": "Advanced Course",
        "description": "In-depth training",
        "status": "active",
        "publish_status": "published"
      },
      "relationships": {
        "site": {
          "data": {
            "id": "123",
            "type": "sites"
          }
        }
      }
    }
  ]
}

Filter by Title Contains

Use the filter[title_cont] parameter to find products where the title contains specific text:

Get products with titles containing "course"

  • GET /v1/products?filter[title_cont]=course

Response will include products with matching titles

{
  "data": [{
    "id": "456",
    "type": "products",
    "attributes": {
      "title": "Advanced Course",
      "description": "In-depth training",
      "status": "active",
      "publish_status": "published"
    }
  },
  {
    "id": "789",
    "type": "products",
    "attributes": {
      "title": "Beginner Course",
      "description": "Introduction to basics",
      "status": "active",
      "publish_status": "published"
    }
  }]
}

Filter by Description Contains

Use the filter[description_cont] parameter to find products where the description contains specific text:

Get products with descriptions containing "training"

  • GET /v1/products?filter[description_cont]=training

Response will include products with matching descriptions

{
  "data": [{
    "id": "456",
    "type": "products",
    "attributes": {
      "title": "Advanced Course",
      "description": "In-depth training program",
      "status": "active",
      "publish_status": "published"
    }
  },
  {
    "id": "789",
    "type": "products",
    "attributes": {
      "title": "Professional Course",
      "description": "Professional training and certification",
      "status": "active",
      "publish_status": "published"
    }
  }]
}

Filter by Status

Use the filter[status_eq] parameter to find products with a specific status:

Get ready products

  • GET /v1/products?filter[status_eq]=ready

Response will include products with matching status

{
  "data": [{
    "id": "456",
    "type": "products",
    "attributes": {
      "title": "Advanced Course",
      "description": "In-depth training program",
      "status": "ready",
      "publish_status": "published"
    }
  },
  {
    "id": "789",
    "type": "products",
    "attributes": {
      "title": "Professional Course",
      "description": "Professional training and certification",
      "status": "ready",
      "publish_status": "published"
    }
  }]
}

Using Multiple Parameters Together

You can combine pagination, sorting, sparse fields and filtering in a single request:

Get page 2 of products for site 123, sorted by title descending, including only title and publish_status fields

  • GET /v1/products?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[products]=title,publish_status

Response will include paginated and filtered products with sparse fields

{
  "data": [
    {
      "id": "456",
      "type": "products",
      "attributes": {
        "title": "Beginner Course",
        "publish_status": "draft"
      },
      "relationships": {
        "site": {
          "data": {
            "id": "123",
            "type": "sites"
          }
        }
      }
    }
  ],
  "links": {
    "self": "https://api.kajabi.com/v1/products?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[products]=title,publish_status",
    "first": "https://api.kajabi.com/v1/products?page[number]=1&page[size]=10&sort=-title&filter[site_id]=123&fields[products]=title,publish_status",
    "prev": "https://api.kajabi.com/v1/products?page[number]=1&page[size]=10&sort=-title&filter[site_id]=123&fields[products]=title,publish_status",
    "next": null,
    "last": "https://api.kajabi.com/v1/products?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[products]=title,publish_status"
  },
  "meta": {
    "total_pages": 2,
    "total_count": 15,
    "current_page": 2
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: title, description, status, for descending order use '-' e.g. &sort=-title

page[number]
number
page[size]
number

Number of documents

fields[products]
string

Partial attributes as specified, e.g. fields[products]=title,publish_status

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[title_cont]
string

Filter by title contains, for example ?filter[title_cont]=marketing

filter[description_cont]
string

Filter by description contains, for example ?filter[description_cont]=marketing

filter[status_eq]
string

Filter by status equals, for example ?filter[status_eq]=ready

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/products/{id}

Show details of a product

Sparse Fields

Use the fields[products] parameter to request only specific attributes:

Get only title and publish_status fields

  • GET /v1/products/123?fields[products]=title,publish_status

Response will only include the requested fields

{
  "data": {
    "id": "123",
    "type": "products",
    "attributes": {
      "title": "Advanced Course",
      "publish_status": "published"
    },
    "relationships": {}
  }
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
fields[products]
string

Partial attributes as specified, e.g. fields[products]=title,publish_status

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

Custom Fields

/custom_fields

Custom Field attributes

The 'handle' attribute may be used as a key for a contact resource, e.g. custom_1, custom_2, custom_3

Pagination

Use page[number] and page[size] parameters to paginate results:

Get first page of 10 items

  • GET /v1/custom_fields?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/custom_fields?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://app.kajabi.com/api/v1/custom_fields?page[number]=2&page[size]=10",
    "first": "https://app.kajabi.com/api/v1/custom_fields?page[number]=1&page[size]=10",
    "prev": "https://app.kajabi.com/api/v1/custom_fields?page[number]=1&page[size]=10",
    "next": "https://app.kajabi.com/api/v1/custom_fields?page[number]=3&page[size]=10",
    "last": "https://app.kajabi.com/api/v1/custom_fields?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Filter by Site ID

Use the filter[site_id] parameter to get custom fields for a specific site:

Get custom fields for site with ID 123

  • GET /v1/custom_fields?filter[site_id]=123

Response will only include custom fields for that site

{
  "data": [
    {
      "id": "123",
      "type": "custom_fields",
      "attributes": {
        "handle": "custom_1",
        "title": "Favorite Song",
        "type": "TextField",
        "required": false
      },
      "relationships": {
        "site": {
          "data": {
            "id": "123",
            "type": "sites"
          }
        }
      }
    }
  ]
}

Sorting

Use the sort parameter to sort the results:

Sort by title in ascending order

  • GET /v1/custom_fields?sort=title

Sort by title in descending order

  • GET /v1/custom_fields?sort=-title

Filter by Title Contains

Use the filter[title_cont] parameter to find custom fields where the title contains specific text:

Get custom fields with titles containing "favorite"

  • GET /v1/custom_fields?filter[title_cont]=favorite

Response will include custom fields with matching titles

{
  "data": [{
    "id": "123",
    "type": "custom_fields",
    "attributes": {
      "handle": "custom_1",
      "title": "Favorite Song",
      "type": "TextField",
      "required": false
    }
  },
  {
    "id": "456",
    "type": "custom_fields",
    "attributes": {
      "handle": "custom_2",
      "title": "Favorite Movie",
      "type": "TextField",
      "required": false
    }
  }]
}

Filter by Required Field

Use the filter[required_eq] parameter to find custom fields based on their required status:

Get custom fields that are required

  • GET /v1/custom_fields?filter[required_eq]=true

Response will include custom fields that are required

{
  "data": [{
    "id": "123",
    "type": "custom_fields",
    "attributes": {
      "handle": "custom_1",
      "title": "Phone Number",
      "type": "TextField",
      "required": true
    }
  }]
}

Using Multiple Parameters Together

You can combine pagination, sorting, sparse fields and filtering in a single request:

Get page 2 of custom fields for site 123, sorted by title descending, including only handle and title fields

  • GET /v1/custom_fields?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[custom_fields]=handle,title

Response will include paginated and filtered custom fields with sparse fields

{
  "data": [
    {
      "id": "456",
      "type": "custom_fields",
      "attributes": {
        "handle": "custom_2",
        "title": "Favorite Movie"
      },
      "relationships": {
        "site": {
          "data": {
            "id": "123",
            "type": "sites"
          }
        }
      }
    }
  ],
  "links": {
    "self": "https://app.kajabi.com/api/v1/custom_fields?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[custom_fields]=handle,title",
    "first": "https://app.kajabi.com/api/v1/custom_fields?page[number]=1&page[size]=10&sort=-title&filter[site_id]=123&fields[custom_fields]=handle,title",
    "prev": "https://app.kajabi.com/api/v1/custom_fields?page[number]=1&page[size]=10&sort=-title&filter[site_id]=123&fields[custom_fields]=handle,title",
    "next": null,
    "last": "https://app.kajabi.com/api/v1/custom_fields?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[custom_fields]=handle,title"
  },
  "meta": {
    "total_pages": 2,
    "total_count": 15,
    "current_page": 2
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: title, handle, type, required for descending order use '-' e.g. &sort=-title

page[number]
number
page[size]
number

Number of documents

fields[custom_fields]
string

Partial attributes as specified, e.g. fields[custom_fields]=handle,title,required

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[title_cont]
string

Filter by title contains, for example ?filter[title_cont]=favorite

filter[type_eq]
string

Filter by field type equals, for example ?filter[type_eq]=TextField

filter[required_eq]
string

Filter by required field equals, for example ?filter[required_eq]=true

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/custom_fields/{id}

Custom Field attributes

  • handle (string) - The key for a contact resource, e.g. custom_1, custom_2, custom_3
  • title (string) - The title of the custom field
  • type (string) - The type of the custom field
  • required (boolean) - Whether the custom field is required
  • archived (boolean) - Whether the custom field is archived

Sparse Fields

Use the fields[custom_fields] parameter to include only specific attributes:

Include only handle and title fields

  • GET /v1/custom_fields/123?fields[custom_fields]=handle,title

Response will include only the specified fields

{
  "data": {
    "id": "123",
    "type": "custom_fields",
    "attributes": {
      "handle": "custom_1",
      "title": "Favorite Song"
    }
  }
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
fields[custom_fields]
string

Partial attributes as specified, e.g. fields[custom_fields]=title,handle

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

Customers

/customers

List of customers

Pagination

Use page[number] and page[size] parameters to paginate results:

Get first page of 10 items

  • GET /v1/customers?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/customers?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://app.kajabi.com/api/v1/customers?page[number]=2&page[size]=10",
    "first": "https://app.kajabi.com/api/v1/customers?page[number]=1&page[size]=10",
    "prev": "https://app.kajabi.com/api/v1/customers?page[number]=1&page[size]=10",
    "next": "https://app.kajabi.com/api/v1/customers?page[number]=3&page[size]=10",
    "last": "https://app.kajabi.com/api/v1/customers?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Sorting

  • The default Sorting is by created_at in descending order (newest first)

Sorting by created_at in ascending order (oldest first)

  • GET /v1/customers?filter[site_id]=123&sort=created_at

Use the sort parameter to sort the results:

Sort by name in ascending order

  • GET /v1/customers?filter[site_id]=123&sort=name

Sort by email in descending order

  • GET /v1/customers?filter[site_id]=123&sort=-email

Sort by net_revenue in ascending order

  • GET /v1/customers?filter[site_id]=123&sort=net_revenue

Sort by last_request_at in descending order

  • GET /v1/customers?filter[site_id]=123&sort=-last_request_at

Response will include customers sorted by the specified field

{
  "data": [{
    "id": "123",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "external_user_id": "cust_123"
    }
  }]
}

Sparse Fields

Use the fields[customers] parameter to request only specific attributes:

Only return name and email attributes

  • GET /v1/customers?fields[customers]=name,email

Response will only include requested fields

{
  "data": [{
    "id": "123",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]"
    }
  }]
}

Filtering

Use the filter[site_id] parameter to filter customers by site:

Get customers for site with ID 123

  • GET /v1/customers?filter[site_id]=123

Response will include only customers from the specified site

{
  "data": [{
    "id": "456",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "external_user_id": "cust_123"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Use the use_indexed_data parameter along with filter[site_id] and filter[search] to search customers using an alternative search algorithm:

Search for customers containing "smith" in site with ID 123 using indexed data

  • GET /v1/customers?filter[site_id]=123&filter[search]=smith&use_indexed_data=true

Response will include matching contacts using the indexed search algorithm

{
  "data": [{
    "id": "456",
    "type": "customers",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Using Multiple Filters

You can combine multiple filter parameters to refine your search:

Get customers from site 123 matching search term

  • GET /v1/customers?filter[site_id]=123&filter[search]=smith

Response will include only customers from the specified site matching the search term

{
  "data": [{
    "id": "456",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "external_user_id": "cust_123"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filtering by Site and Offer

You can filter customers by both site and offer ownership:

Get customers from site 123 who have been granted offer 789

  • GET /v1/customers?filter[site_id]=123&filter[has_offer_id]=789

Response will include only customers from the specified site who have been granted the offer

{
  "data": [{
    "id": "456",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "external_user_id": "cust_123"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      },
      "offers": {
        "links": {
          "self": "https://app.kajabi.com/api/v1/customers/456/relationships/offers",
          "related": "https://app.kajabi.com/api/v1/customers/456/offers"
        }
      }
    }
  }]
}

Filtering by Site and Product

You can filter customers by both site and product ownership:

Get customers from site 123 who have purchased product 789

  • GET /v1/customers?filter[site_id]=123&filter[has_product_id]=789

Response will include only customers from the specified site who have purchased the product

{
  "data": [{
    "id": "456",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "external_user_id": "cust_123"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      },
      "offers": {
        "links": {
          "self": "https://app.kajabi.com/api/v1/customers/456/relationships/offers",
          "related": "https://app.kajabi.com/api/v1/customers/456/offers"
        }
      }
    }
  }]
}

Using Multiple Parameters Together

You can combine filtering, sparse fields, pagination and search in a single request:

Get page 2 of customers from site 123, including only name and email fields, searching for "smith"

  • GET /v1/customers?filter[site_id]=123&fields[customers]=name,email&page[number]=2&page[size]=10&filter[search]=smith

Response will include paginated, filtered customers with sparse fields

{
  "data": [{
    "id": "456",
    "type": "customers",
    "attributes": {
      "name": "John Smith",
      "email": "[email protected]"
    }
  }],
  "links": {
    "self": "https://app.kajabi.com/api/v1/customers?filter[site_id]=123&fields[customers]=name,email&page[number]=2&page[size]=10&filter[search]=smith",
    "first": "https://app.kajabi.com/api/v1/customers?filter[site_id]=123&fields[customers]=name,email&page[number]=1&page[size]=10&filter[search]=smith",
    "prev": "https://app.kajabi.com/api/v1/customers?filter[site_id]=123&fields[customers]=name,email&page[number]=1&page[size]=10&filter[search]=smith",
    "next": null,
    "last": "https://app.kajabi.com/api/v1/customers?filter[site_id]=123&fields[customers]=name,email&page[number]=2&page[size]=10&filter[search]=smith"
  },
  "meta": {
    "total_pages": 2,
    "total_count": 15,
    "current_page": 2
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: name, email, created_at, net_revenue, last_request_at for descending order use '-' e.g. &sort=-name

page[number]
number
page[size]
number

Number of documents

fields[customers]
string

Sparse fields, use: name, email for example ?fields[customers]=name,email

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[search]
string

Filter with fuzzy search of name/email, for example ?filter[search]=alexa

filter[has_offer_id]
string

Filter based on granted offer, for example ?filter[has_offer_id]=111

filter[has_product_id]
string

Filter based on product purchase, for example ?filter[has_product_id]=222

use_indexed_data
string

Alternative algorithm for searching/filtering (in some cases performs faster), for example ?use_indexed_data=true

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/customers/{id}

Show customer details

  • The name and email attributes are kept in sync with the related contact resource
  • The external_user_id attribute may be used as a customer reference in an external system

Customer Attributes

  • name (string) - The customer's full name. This is a required field and can be either user-provided or auto-generated from their email address if left blank.
  • email (string) - The customer's email address. This is a required field and must be unique within a site. It's automatically downcased and stripped of whitespace. Used for authentication and communication.
  • avatar (string) - A URL to the customer's profile image. Can be either a custom uploaded avatar or falls back to Gravatar. If not set, defaults to a blank image.
  • external_user_id (string) - An optional external identifier that can be used to link the customer to external systems. Must be unique within a site.
  • public_bio (string) - A text field containing the customer's public biography or description. This is optional and can be displayed in community/social features.
  • public_location (string) - A text field for the customer's public location information. Optional field used for community/social features.
  • public_website (string) - The customer's website URL. This is validated to ensure it's a proper URL format and is transformed to ensure proper formatting.
  • socials (object) - A collection of the customer's social media links and profiles.
  • net_revenue (string) - The total revenue generated by this customer through their purchases. This is calculated from their successful payment transactions.
  • sign_in_count (integer) - A counter tracking how many times the customer has signed into their account.
  • last_request_at (string) - Timestamp of the customer's most recent activity or request. Used to track user engagement and activity.
  • bounced_at (string) - Timestamp indicating when the customer's email started bouncing. This is reset if the email address is changed.
  • created_at (string) - Timestamp when the customer record was created.
  • updated_at (string) - Timestamp when the customer record was last updated.

Use the include parameter to include related resources:

Include offers and products

  • GET /v1/customers/123?include=contact,offers,products

Response will include related resources

{
  "data": {
    "id": "123",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]",
      "avatar": null,
      "external_user_id": "cust_123",
      "public_bio": null,
      "public_location": null,
      "public_website": null,
      "socials": null,
      "net_revenue": "0.0",
      "sign_in_count": 0,
      "last_request_at": null,
      "bounced_at": null,
      "created_at": "2021-01-01T00:00:00Z",
      "updated_at": "2021-01-01T00:00:00Z"
    },
    "links": {
      "contact": "https://app.kajabi.com/api/v1/contacts/321"
    },
    "relationships": {
      "contact": {
        "data": {
          "id": "321",
          "type": "contacts"
        }
      },
      "offers": {
        "data": [{ "id": "456", "type": "offers" }],
        "links": {
          "self": "https://app.kajabi.com/api/v1/customers/123/relationships/offers"
        }
      },
      "products": {
        "data": [{ "id": "789", "type": "products" }]
      }
    }
  },
  "included": [
    {
      "id": "456",
      "type": "offers",
      "attributes": {
        "name": "Offer 1",
        "description": "Offer 1 description",
        "internal_title": "Offer 1",
        "price_in_cents": 0,
        "payment_type": "free",
        "token": "offer_123",
        "payment_method": "none",
        "price_description": "Free",
        "checkout_url": "https://mywebsite.com/offers/456",
        "recurring_offer": false,
        "subscription": false,
        "one_time": true,
        "single": false,
        "free": true
      }
    },
    {
      "id": "789",
      "type": "products",
      "attributes": {
        "created_at": "2024-11-12T23:43:09.551Z",
        "title": "Course 1",
        "description": "Course 1 description",
        "status": "ready",
        "members_aggregate_count": 0,
        "product_type_name": "Course",
        "product_type_id": 789,
        "publish_status": "published",
        "thumbnail_url": null
      }
    },
    {
      "id": "321",
      "type": "contacts",
      "attributes": {
        "name": "Alice Smith",
        "email": "[email protected]",
        "address_line_1": null,
        "address_line_2": null,
        "address_city": null,
        "address_country": null,
        "address_state": null,
        "address_zip": null,
        "phone_number": null,
        "business_number": null,
        "subscribed": false,
        "external_user_id": null,
        "created_at": "2024-11-20T18:53:19.389Z",
        "updated_at": "2024-11-20T18:53:19.389Z"
      }
    }
  ]
}

Sparse Fields

Use the fields[customers] parameter to request only specific attributes:

Only return name and email attributes

  • GET /v1/customers/123?fields[customers]=name,email

Response will only include requested fields

{
  "data": {
    "id": "123",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith",
      "email": "[email protected]"
    }
  }
}

Using Multiple Parameters Together

You can combine filtering, sparse fields, pagination and search in a single request:

  • GET /v1/customers/123?include=products&fields[customers]=name&fields[product]=title

Response will include related resources with sparse fields

{
  "data": {
    "id": "123",
    "type": "customers",
    "attributes": {
      "name": "Alice Smith"
    },
    "relationships": {}
  },
  "included": [
    {
      "id": "789",
      "type": "products",
      "attributes": {
        "title": "Course 1"
      }
    }
  ]
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
include
string

with ?include=offers,products the response will include the related resources

fields[customers]
string

Partial attributes as specified, e.g. fields[customers]=name,email

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

/customers/{id}/relationships/offers

Get the customer's relationship to offers (granted).

Response is a list of resource identifiers

{
  "data": [
    { "type": "offers", "id": "123" },
    { "type": "offers", "id": "456" }
  ]
}

The related tag resources are available using the GET api/v1/offers endpoint. The resource identifier includes the offer id and type. Example URLs: /api/v1/offers/123, /api/v1/offers/456

Authorizations:
Bearer
path Parameters
customer_id
required
string

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/customers/{id}/relationships/offers

Grant offer(s) to a customer

Create an offer grant for a customer.

In the request body inlcude offer resource identifier(s), id: OFFER_ID, type: "offers".

{ "data": [{"type": "offers", "id": "123"}] }

Response

  • A successful response body will list the offers related to the customer
  • An error response will include a JSON body with error details.

Behaviors and side effects

  • Checks if the customerwas already granted the offer
  • May send a gift granted email if this is a gift offer
  • Triggers automations if configured
Authorizations:
Bearer
path Parameters
customer_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifiers)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/customers/{id}/relationships/offers

Revoke offer grant(s) for a customer

Revoke offer grant(s) using a list of resource identifiers In the request body inlcude offer resource identifier(s), id: OFFER_ID, type: "offers".

{ "data": [{"type": "offers", "id": "123"}] }

Response

  • A successful response body will list the offers related to the customer
  • An error response will include a JSON body with error details.

Behaviors and side effects

  • Only affects active offers
  • Handles both offer purchases and offer grants
  • Deactivates all associated product memberships
Authorizations:
Bearer
path Parameters
customer_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifiers)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/customers/{id}/relationships/offers

Replace offer grant(s) for a customer

Replace offer grants (grants and revokes offers to/from customer) using a list of resource identifiers In the request body inlcude offer resource identifier(s), id: OFFER_ID, type: "offers".

{ "data": [{"type": "offers", "id": "456"}, {"type": "offers", "id": "789"}] }

Response

  • A successful response body will list the offers related to the customer
  • An error response will include a JSON body with error details.
Authorizations:
Bearer
path Parameters
customer_id
required
string
Request Body schema: application/vnd.api+json
required
Array of objects (resource_identifier)

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

Forms

/forms

Contact forms for a site

Pagination

Use page[number] and page[size] parameters to paginate results:

Get first page of 10 items

  • GET /v1/forms?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/forms?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://api.kajabi.com/v1/forms?page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/forms?page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/forms?page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/forms?page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/forms?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Sorting

Use the sort parameter to sort the results:

Sort by title in ascending order

  • GET /v1/forms?sort=title

Sort by title in descending order

  • GET /v1/forms?sort=-title

Response will include forms sorted by the specified field

{
  "data": [
    {
      "id": "123",
      "type": "forms",
      "attributes": {
        "title": "Contact Form A",
        "description": "General contact form"
      }
    },
    {
      "id": "456",
      "type": "forms",
      "attributes": {
        "title": "Contact Form B",
        "description": "Newsletter signup form"
      }
    }
  ]
}

Sparse Fields

Use the fields[forms] parameter to request only specific attributes:

Only return title and description attributes

  • GET /v1/forms?fields[forms]=title,description

Response will only include requested fields

{
  "data": [{
    "id": "123",
    "type": "forms",
    "attributes": {
      "title": "Contact Form A",
      "description": "General contact form"
    }
  }]
}

Filter by Site ID

Use the filter[site_id] parameter to get forms for a specific site:

Get forms for site with ID 123

  • GET /v1/forms?filter[site_id]=123

Response will only include forms for that site

{
  "data": [{
    "id": "456",
    "type": "forms",
    "attributes": {
      "title": "Contact Form A",
      "description": "General contact form"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filter by Title Contains

Use the filter[title_cont] parameter to find forms where the title contains specific text:

Get forms with titles containing "course"

  • GET /v1/forms?filter[title_cont]=course

Response will include forms with matching titles

{
  "data": [{
    "id": "456",
    "type": "forms",
    "attributes": {
      "title": "Course Registration Form",
      "description": "Sign up form for online courses"
    }
  }]
}

Using Multiple Parameters Together

You can combine pagination, sorting, sparse fields and filtering in a single request:

Get page 2 of forms for site 123, sorted by title descending, including only title and description fields

  • GET /v1/forms?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[forms]=title,description

Response will include paginated and filtered forms with sparse fields

{
  "data": [
    {
      "id": "456",
      "type": "forms",
      "attributes": {
        "title": "Newsletter Form",
        "description": "Newsletter signup form"
      },
      "relationships": {
        "site": {
          "data": {
            "id": "123",
            "type": "sites"
          }
        }
      }
    }
  ],
  "links": {
    "self": "https://api.kajabi.com/v1/forms?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[forms]=title,description",
    "first": "https://api.kajabi.com/v1/forms?page[number]=1&page[size]=10&sort=-title&filter[site_id]=123&fields[forms]=title,description",
    "prev": "https://api.kajabi.com/v1/forms?page[number]=1&page[size]=10&sort=-title&filter[site_id]=123&fields[forms]=title,description",
    "next": null,
    "last": "https://api.kajabi.com/v1/forms?page[number]=2&page[size]=10&sort=-title&filter[site_id]=123&fields[forms]=title,description"
  },
  "meta": {
    "total_pages": 2,
    "total_count": 15,
    "current_page": 2
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: title for descending order use '-' e.g. &sort=-title

page[number]
integer
page[size]
integer

Number of documents

fields[forms]
string

Partial attributes as specified, e.g. fields[forms]=title

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[title_cont]
string

Filter by title contains, for example ?filter[title_cont]=course

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ]
}

forms/{id}

Shows details of a form

Forms belong to a site and can be associated with:

  • Landing pages
  • Offers
  • Email sequences
  • Events
  • Newsletters

Form Attributes

  • title (string) - A required field that represents the name or heading of the form. This is used to identify and display the form in the user interface. Forms must have a unique title within a site and can be searched and sorted by this attribute.
  • default (boolean) - A boolean flag indicating whether this is the default form for the site. Each site can have one default form, which is typically used when no specific form is specified. The default form can be accessed using the special ID "default" in API calls. When true, this form is considered the site's primary contact form.
  • webhook_url (string) - An optional URL where form submission data will be sent via webhook. This allows integration with external systems. The URL:
    • Must be a valid URL format
    • Cannot be a redirecting URL
    • Is automatically transformed and validated
    • Can be used to send form submission data to external services
  • created_at (string) - Timestamp indicating when the form was created. This is automatically set when the form is first created.
  • updated_at (string) - Timestamp indicating when the form was last modified. This is automatically updated whenever the form is changed.

Use the include parameter to load related resources:

Include fields, offer, contact_tags

  • GET /v1/forms/123?include=fields,offer,contact_tags

Response will include the requested related resources

{
  "data": {
    "id": "123",
    "type": "forms",
    "attributes": {
      "title": "Contact Form",
      "default": false,
      "webhook_url": null,
      "created_at": "2025-02-27T01:03:09.179Z",
      "updated_at": "2025-02-27T01:03:25.365Z"
    },
    "relationships": {
      "fields": {
        "data": [
          { "id": "456", "type": "fields" },
          { "id": "789", "type": "fields" }
        ]
      },
      "offer": {
        "data": { "id": "123", "type": "offers" }
      },
      "contact_tags": {
        "data": [
          { "id": "456", "type": "contact_tags" },
          { "id": "789", "type": "contact_tags" }
        ]
      }
    }
  },
  "included": [
    {
      "id": "456",
      "type": "fields", "attributes": { "name": "Name" }
    },
    {
      "id": "789",
      "type": "fields", "attributes": { "name": "Email" }
    },
    {
      "id": "123",
      "type": "offers", "attributes": { "name": "Offer A" }
    },
    {
      "id": "456",
      "type": "contact_tags", "attributes": { "name": "Tag A" }
    },
    {
      "id": "789",
      "type": "contact_tags", "attributes": { "name": "Tag B" }
    }
  ]
}

Field Attributes

Fields are used in:

  • Contact forms
  • Offer forms
  • Custom field sets
  • Form submissions

The system maintains default fields like name, email, etc. that cannot be removed

  • title (string) - The display name or label of the field. This is a required attribute that represents how the field will be shown to users in forms and interfaces. Aside from default fields, custom fields can have user-defined titles.
  • type (string) - The type of field, which must be one of these predefined types:
    • TextField - Standard text input
    • PhoneField - Phone number input
    • EmailField - Email address input
    • TextAreaField - Multi-line text input
    • CheckboxField - Boolean checkbox
    • SelectBoxField - Dropdown select
    • RadioButtonsField - Radio button group
    • CountryField - Country selector
    • MobilePhoneField - Mobile phone input
  • required (boolean) - A boolean indicating whether the field must be filled out. For default fields, this is set in the configuration, while custom fields can be marked as required or optional.
  • handle (string) - A unique identifier for the field within a site.
    • A custom handle in the format custom_N where N is a number from 1 to 150
    • The handle is used to reference the field in code and templates.
  • select_options (string) - For fields that have choices (SelectBoxField, RadioButtonsField), this contains the available options. The options are stored as newline-separated values and must be unique within the field.
  • editable (boolean) - A boolean indicating whether the field can be modified. Default fields typically have this set to false, while custom fields can be editable.
  • created_at (string) - Timestamp when the field was created.
  • updated_at (string) - Timestamp when the field was last updated.

Sparse Fields

Use the fields[forms] parameter to request only specific attributes:

Only return title and webhook_url attributes

  • GET /v1/forms/123?fields[forms]=title,webhook_url

Response will only include requested fields

{
  "data": [{
    "id": "123",
    "type": "forms",
    "attributes": {
      "title": "Contact Form A",
      "webhook_url": "https://example.com/webhook"
    }
  }]
}

Using Multiple Parameters Together

You can combine include and sparse fields in a single request:

Include fields (only name attribute) and only return title and webhook_url attributes

  • GET /v1/forms/123?include=fields&fields[forms]=title,webhook_url&&fields[fields]=title

Response will include related fields with sparse fields

{
  "data": {
    "id": "123",
    "type": "forms",
    "attributes": {
      "title": "Contact Form A",
      "webhook_url": "https://example.com/webhook"
    },
    "relationships": {}
  },
  "included": [
    {
      "id": "456",
      "type": "fields",
      "attributes": {
        "title": "Name"
      }
    },
    {
      "id": "789",
      "type": "fields",
      "attributes": {
        "title": "Email"
      }
    }
  ]
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
include
string

Load the related resources, for example ?include=fields,site,offer,contact_tags

fields[forms]
string

Partial attributes as specified, e.g. fields[forms]=title,webhook_url

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

/forms/{id}/submit

Submit a form

  • The name and email attributes are required.
  • The email attribute must be a valid and deliverable email address.

Example request body:

{
  "data": {
    "type": "form_submissions",
    "attributes": {
      "name": "John Doe",
      "email": "[email protected]"
    }
  }
}

Response will include the newly created form submission resource.

{
  "data": {
    "id": "313",
    "type": "form_submissions",
    "attributes": {
      "name": "John Doe",
      "email": "[email protected]",
      "address_line_1": null,
      "address_line_2": null,
      "address_city": null,
      "address_country": null,
      "address_state": null,
      "address_zip": null,
      "phone_number": null,
      "business_number": null,
      "mobile_phone_number": null
    },
    "relationships": {
      "site": {
        "data": {
          "id": "2",
          "type": "sites"
        }
      },
      "form": {
        "data": {
          "id": "15",
          "type": "forms"
        }
      }
    }
  }
}

Behaviors and side effects

  • Checks for disposable emails
  • Validates email deliverability
  • Sends double opt-in email if needed
  • Subscribes contact (with opt-in handling)
  • Subscribes to SMS if applicable
  • Adds tags to contact
  • Grants offers if configured
  • Subscribes to email sequences
  • Delivers webhooks
  • Triggers automations
Authorizations:
Bearer
path Parameters
id
required
string
Request Body schema: application/vnd.api+json
required
object

Responses

Request samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

Me

/me

Returns the current user's profile data.

Response attributes

The response will include the following attributes:

  • initials - A derived attribute that represents the user's initials based on their name. This is typically used for avatar placeholders or compact user displays. For example, "John Doe" would have initials "JD".
  • name - The user's full name. This is a required field that can be:
    • Set directly as a full name
    • Automatically generated from first name and last name fields when either changes
    • Used for display purposes throughout the platform
  • email - The user's email address. This is a critical field that:
    • Is required and must be unique
    • Is used for authentication
    • Can trigger email change notifications
    • Is used for password recovery
    • Can be marked as bounced (and reset when email changes)
    • Is validated against email format requirements
  • role_level - Represents the user's permission level in the system. This attribute:
    • Common values include:
      • OWNER - Account owner with full permissions
      • ADMINISTRATOR - Admin with site management permissions
      • Determines what actions and resources the user can access
      • Is used for permission checks throughout the system
Authorizations:
Bearer

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    }
}

Offers

/offers

List of offers (not archived) for a site that can be granted to a contact

Pagination

Use page[number] and page[size] parameters to paginate results:

Get first page of 10 items

  • GET /v1/offers?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/offers?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://api.kajabi.com/v1/offers?page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/offers?page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/offers?page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/offers?page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/offers?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Sorting

Use the sort parameter to sort the results:

Sort by title in ascending order

  • GET /v1/offers?sort=title

Sort by title in descending order

  • GET /v1/offers?sort=-title

Response will include offers sorted by the specified field

{
  "data": [
    {
      "id": "123",
      "type": "offers",
      "attributes": {
        "title": "Advanced Course Bundle",
        "price_in_cents": 19900,
        "status": "active"
      }
    },
    {
      "id": "456",
      "type": "offers",
      "attributes": {
        "title": "Beginner Course Bundle",
        "price_in_cents": 9900,
        "status": "active"
      }
    }
  ]
}

Sparse Fields

Use the fields[offers] parameter to request only specific attributes:

Only return title and price_in_cents attributes

  • GET /v1/offers?fields[offers]=title,price_in_cents

Response will only include requested fields

{
  "data": [{
    "id": "123",
    "type": "offers",
    "attributes": {
      "title": "Advanced Course Bundle",
      "price_in_cents": 19900
    }
  }]
}

Filter by Site ID

Use the filter[site_id] parameter to get offers for a specific site:

Get offers for site with ID 123

  • GET /v1/offers?filter[site_id]=123

Response will only include offers for that site

{
  "data": [{
    "id": "456",
    "type": "offers",
    "attributes": {
      "title": "Advanced Course Bundle",
      "price_in_cents": 19900,
      "status": "active"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Filter by Title Contains

Use the filter[title_cont] parameter to find offers where the title contains specific text:

Get offers with titles containing "bundle"

  • GET /v1/offers?filter[title_cont]=bundle

Response will include offers with matching titles

{
  "data": [{
    "id": "456",
    "type": "offers",
    "attributes": {
      "title": "Advanced Course Bundle",
      "price_in_cents": 19900,
      "status": "active"
    }
  },
  {
    "id": "789",
    "type": "offers",
    "attributes": {
      "title": "Basic Course Bundle",
      "price_in_cents": 9900,
      "status": "active"
    }
  }]
}

Filter by Description Contains

Use the filter[description_cont] parameter to find offers where the description contains specific text:

Get offers with descriptions containing "marketing"

  • GET /v1/offers?filter[description_cont]=marketing

Response will include offers with matching descriptions

{
  "data": [{
    "id": "456",
    "type": "offers",
    "attributes": {
      "title": "Marketing Course Bundle",
      "description": "Complete marketing course bundle with advanced strategies",
      "price_in_cents": 19900,
      "status": "active"
    }
  },
  {
    "id": "789",
    "type": "offers",
    "attributes": {
      "title": "Business Essentials",
      "description": "Business fundamentals including marketing and sales",
      "price_in_cents": 9900,
      "status": "active"
    }
  }]
}

Filter by Price Description

Use the filter[price_description_eq] parameter to find offers with a specific price description:

Get offers with price description "Free"

  • GET /v1/offers?filter[price_description_eq]=Free

Response will include offers with matching price description

{
  "data": [{
    "id": "456",
    "type": "offers",
    "attributes": {
      "title": "Premium Course Bundle",
      "price_in_cents": 0,
      "price_description": "Free",
      "status": "active"
    }
  },
  {
    "id": "789",
    "type": "offers",
    "attributes": {
      "title": "Basic Course Bundle",
      "price_in_cents": 0,
      "price_description": "Free",
      "status": "active"
    }
  }]
}

Using Multiple Parameters Together

You can combine pagination, sorting, sparse fields and filtering in a single request:

Get page 2 of offers for site 123, sorted by price_in_cents descending, including only title and price_in_cents fields

  • GET /v1/offers?page[number]=2&page[size]=10&sort=-price_in_cents&filter[site_id]=123&fields[offers]=title,price_in_cents

Response will include paginated and filtered offers with sparse fields

{
  "data": [
    {
      "id": "456",
      "type": "offers",
      "attributes": {
        "title": "Basic Course Bundle",
        "price_in_cents": 9900
      },
      "relationships": {
        "site": {
          "data": {
            "id": "123",
            "type": "sites"
          }
        }
      }
    }
  ],
  "links": {
    "self": "https://api.kajabi.com/v1/offers?page[number]=2&page[size]=10&sort=-price_in_cents&filter[site_id]=123&fields[offers]=title,price_in_cents",
    "first": "https://api.kajabi.com/v1/offers?page[number]=1&page[size]=10&sort=-price_in_cents&filter[site_id]=123&fields[offers]=title,price_in_cents",
    "prev": "https://api.kajabi.com/v1/offers?page[number]=1&page[size]=10&sort=-price_in_cents&filter[site_id]=123&fields[offers]=title,price_in_cents",
    "next": null,
    "last": "https://api.kajabi.com/v1/offers?page[number]=2&page[size]=10&sort=-price_in_cents&filter[site_id]=123&fields[offers]=title,price_in_cents"
  },
  "meta": {
    "total_pages": 2,
    "total_count": 15,
    "current_page": 2
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: title, price_in_cents, for descending order use '-' e.g. &sort=-price_in_cents

page[number]
number
page[size]
number

Number of documents

fields[offers]
string

Partial attributes as specified, e.g. fields[offers]=title,price_in_cents

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[title_cont]
string

Filter by title contains, for example ?filter[title_cont]=course

filter[description_cont]
string

Filter by description contains, for example ?filter[description_cont]=course

filter[price_description_eq]
string

Filter by exact price description, for example ?filter[price_description_eq]=Free

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/offers/{id}

The offer system is a core part of Kajabi's e-commerce functionality, allowing course creators and digital product owners to monetize their content through various pricing and payment models while maintaining flexibility in how offers are presented and processed.

Offer attributes

  • title (string) - Required, public name of the offer shown to customers
  • description (string) - Optional, detailed information about what's included in the offer
  • internal_title (string) - Optional, for internal reference/organization (not shown to customers)
  • currency (string) - The currency of the offer, defaults to USD
  • price_in_cents (integer) - The USD price in cents (for precise decimal handling)
  • payment_type (string) - Indicates the payment structure
  • token (string) - A unique identifier for the offer, particularly in checkout URLs
  • payment_method (string) - Indicates the payment method, Returns empty string if no payment method is set
  • price_description (string) - Human-readable representation of the offer's price, includes formatting and currency information
  • checkout_url (string) - Full URL where customers can purchase the offer
    • Includes the offer token for identification
    • Uses the site's public host and protocol settings
  • recurring_offer (boolean) - Whether the offer has recurring payments
  • subscription (boolean) - Whether the offer is a subscription offer
  • one_time (boolean) - Whether the offer is a one-time offer
  • single (boolean) - Whether the offer is a single offer
  • free (boolean) - Whether the offer is a free offer

Include Relationships

Use the include parameter to include related products:

  • GET /v1/offers/123?include=products

Response will include products relationship

{
  "data": {
    "id": "123",
    "type": "offers",
    "attributes": {
      "title": "Advanced Course Bundle",
      "description": "Complete advanced course bundle with expert guidance",
      "internal_title": "advanced_course_bundle",
      "currency": "USD",
      "price_in_cents": 19900,
      "payment_type": "stripe",
      "token": "123",
      "payment_method": "stripe",
      "price_description": "$199.00",
      "checkout_url": "https://api.kajabi.com/checkout/123",
      "recurring_offer": false,
      "subscription": false,
      "one_time": true,
      "single": true,
      "free": false,
      "thumbnail_url": "https://api.kajabi.com/images/456"
    },
    "relationships": {
      "products": {
        "data": [
          {
            "id": "456",
            "type": "products"
          }
        ]
      }
    }
  },
  "included": [
    {
      "id": "456",
      "type": "products",
      "attributes": {
        "created_at": "2021-01-01T00:00:00Z",
        "title": "Advanced Course",
        "description": "Complete advanced course with expert guidance",
        "status": "ready",
        "members_aggregate_count": 100,
        "product_type_name": "Course",
        "product_type_id": 456,
        "publish_status": "published",
        "thumbnail_url": "https://api.kajabi.com/images/456"
      }
    }
  ]
}

Sparse Fields

Only return title and price_in_cents attributes

  • GET /v1/offers/123?fields[offers]=title,price_in_cents

Response will only include requested fields

{
  "data": {
    "id": "123",
    "type": "offers",
    "attributes": {
      "title": "Advanced Course Bundle",
      "price_in_cents": 19900
    }
  }
}

Multiple parameters together

You can combine include and sparse fields in a single request:

Get offer 123 with products, including only title and description fields, and products with title and publish_status fields

  • GET /v1/offers/123?include=products&fields[offers]=title,description&fields[products]=title,publish_status

Response will include offer and products with sparse fields

{
  "data": {
    "id": "123",
    "type": "offers",
    "attributes": {
      "title": "Advanced Course Bundle",
      "description": "Complete advanced course bundle with expert guidance"
    },
    "relationships": {}
  },
  "included": [
    {
      "id": "456",
      "type": "products",
      "attributes": {
        "title": "Advanced Course",
        "publish_status": "published"
      }
    }
  ]
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
include
string

Load the related resources, for example ?include=products

fields[offers]
string

Partial attributes as specified, e.g. fields[offers]=title,price_in_cents

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

/offers/{id}/relationships/products

get the offer's relationship to products, response is a list of resource identifiers

Authorizations:
Bearer
path Parameters
offer_id
required
string

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

Sites

/sites

List of sites that the current user has access to

Pagination

Use page[number] and page[size] parameters to paginate results:

Get first page of 10 items

  • GET /v1/sites?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/sites?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://api.kajabi.com/v1/sites?page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/sites?page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/sites?page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/sites?page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/sites?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Sorting

Use the sort parameter to sort the results:

Sort by title in ascending order

  • GET /v1/sites?sort=title

Sort by title in descending order

  • GET /v1/sites?sort=-title

Response will include sites sorted by the specified field

{
  "data": [
    {
      "id": "123",
      "type": "sites",
      "attributes": {
        "title": "Advanced Training Site",
        "subdomain": "advanced-training"
      }
    },
    {
      "id": "456",
      "type": "sites",
      "attributes": {
        "title": "Beginner Training Site",
        "subdomain": "beginner-training"
      }
    }
  ]
}

Sparse Fields

Use the fields[sites] parameter to request only specific attributes:

Only return title and subdomain attributes

  • GET /v1/sites?fields[sites]=title,subdomain

Response will only include requested fields

{
  "data": [{
    "id": "123",
    "type": "sites",
    "attributes": {
      "title": "Advanced Training Site",
      "subdomain": "advanced-training"
    }
  }]
}

Filter by Title Contains

Use the filter[title_cont] parameter to find sites where the title contains specific text:

Get sites with titles containing "training"

  • GET /v1/sites?filter[title_cont]=training

Response will include sites with matching titles

{
  "data": [{
    "id": "123",
    "type": "sites",
    "attributes": {
      "title": "Advanced Training Site",
      "subdomain": "advanced-training"
    }
  },
  {
    "id": "456",
    "type": "sites",
    "attributes": {
      "title": "Beginner Training Site",
      "subdomain": "beginner-training"
    }
  }]
}

Filter by Subdomain Contains

Use the filter[subdomain_cont] parameter to find sites where the subdomain contains specific text:

Get sites with subdomains containing "training"

  • GET /v1/sites?filter[subdomain_cont]=training

Response will include sites with matching subdomains

{
  "data": [{
    "id": "123",
    "type": "sites",
    "attributes": {
      "title": "Advanced Training Site",
      "subdomain": "advanced-training"
    }
  },
  {
    "id": "456",
    "type": "sites",
    "attributes": {
      "title": "Beginner Training Site",
      "subdomain": "beginner-training"
    }
  }]
}

Using Multiple Parameters Together

You can combine pagination, sorting and sparse fields in a single request:

Get page 2 of sites, sorted by title descending, including only title and subdomain fields

  • GET /v1/sites?page[number]=2&page[size]=10&sort=-title&fields[sites]=title,subdomain

Response will include paginated sites with sparse fields

{
  "data": [
    {
      "id": "456",
      "type": "sites",
      "attributes": {
        "title": "Beginner Training Site",
        "subdomain": "beginner-training"
      }
    }
  ],
  "links": {
    "self": "https://api.kajabi.com/v1/sites?page[number]=2&page[size]=10&sort=-title&fields[sites]=title,subdomain",
    "first": "https://api.kajabi.com/v1/sites?page[number]=1&page[size]=10&sort=-title&fields[sites]=title,subdomain",
    "prev": "https://api.kajabi.com/v1/sites?page[number]=1&page[size]=10&sort=-title&fields[sites]=title,subdomain",
    "next": null,
    "last": "https://api.kajabi.com/v1/sites?page[number]=2&page[size]=10&sort=-title&fields[sites]=title,subdomain"
  },
  "meta": {
    "total_pages": 2,
    "total_count": 15,
    "current_page": 2
  }
}
Authorizations:
Bearer
query Parameters
sort
string

Sort order, use: title, subdomain, for descending order use '-' e.g. &sort=-title

page[number]
number
page[size]
number

Number of documents

fields[sites]
string

Partial attributes as specified, e.g. fields[sites]=title,subdomain

filter[title_cont]
string

Filter by title contains, for example ?filter[title_cont]=training

filter[subdomain_cont]
string

Filter by subdomain contains, for example ?filter[subdomain_cont]=training

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/sites/{id}

The site system is a fundamental part of Kajabi's platform, representing a customer's branded presence and serving as the container for their products, courses, and other content. Each site can be customized extensively while maintaining the core functionality needed for e-learning and digital product delivery.

Site Attributes

  • title (string) - A required field that represents the name of the site
  • subdomain (string) - The subdomain of the site, used for routing and site identification
  • created_at (string) - A read-only timestamp, ISO date string format, that indicates when the site was created
  • updated_at (string) - A read-only timestamp, ISO date string format, that indicates when the site was last modified

Sparse Fields

Use the fields[sites] parameter to request only specific attributes:

Only return title and subdomain attributes

  • GET /v1/sites/123?fields[sites]=title,subdomain

Response will only include requested fields

{
  "data": {
    "id": "123",
    "type": "sites",
    "attributes": {
      "title": "Advanced Training Site",
      "subdomain": "advanced-training"
    }
  }
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
fields[sites]
string

Partial attributes as specified, e.g. fields[sites]=title,subdomain

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

Transactions

/transactions

List of transactions

Pagination

Use page[number] and page[size] parameters to paginate results:

Get first page of 10 items

  • GET /v1/transactions?page[number]=1&page[size]=10

Get second page of 25 items

  • GET /v1/transactions?page[number]=2&page[size]=25

The response includes pagination links and meta data:

{
  "links": {
    "self": "https://api.kajabi.com/v1/transactions?page[number]=2&page[size]=10",
    "first": "https://api.kajabi.com/v1/transactions?page[number]=1&page[size]=10",
    "prev": "https://api.kajabi.com/v1/transactions?page[number]=1&page[size]=10",
    "next": "https://api.kajabi.com/v1/transactions?page[number]=3&page[size]=10",
    "last": "https://api.kajabi.com/v1/transactions?page[number]=5&page[size]=10"
  },
  "meta": {
    "total_pages": 5,
    "total_count": 50,
    "current_page": 2
  }
}

Sparse Fields

Use the fields[transactions] parameter to request only specific attributes:

Only return amount_in_cents and sales_tax_in_cents attributes

  • GET /v1/transactions?fields[transactions]=amount_in_cents,sales_tax_in_cents

Response will only include requested fields

{
  "data": [{
    "id": "123",
    "type": "transactions",
    "attributes": {
      "amount_in_cents": 9900,
      "sales_tax_in_cents": 990
    }
  }]
}

Filtering

Use the filter[site_id] parameter to filter transactions by site:

Get transactions for site with ID 123

  • GET /v1/transactions?filter[site_id]=123

Response will include only transactions for the specified site

{
  "data": [{
    "id": "456",
    "type": "transactions",
    "attributes": {
      "amount_in_cents": 9900,
      "sales_tax_in_cents": 990,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Date Range Filtering

Use the filter[start_date] and filter[end_date] parameters to filter transactions by date range:

Get transactions between January 1st and January 31st, 2024

  • GET /v1/transactions?filter[start_date]=2024-01-01&filter[end_date]=2024-01-31

Response will include only transactions within the specified date range

{
  "data": [{
    "id": "456",
    "type": "transactions",
    "attributes": {
      "amount_in_cents": 9900,
      "sales_tax_in_cents": 990,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }]
}

Using Multiple Parameters Together

You can combine multiple parameters to filter and format the response:

Get paginated, filtered transactions with specific fields

  • GET /v1/transactions?page[number]=1&page[size]=10&fields[transactions]=amount_in_cents,sales_tax_in_cents&filter[site_id]=123&filter[start_date]=2024-01-01&filter[end_date]=2024-01-31

Response will include paginated transactions matching all filters, with only requested fields:

{
  "data": [{
    "id": "456",
    "type": "transactions",
    "attributes": {
      "amount_in_cents": 9900,
      "sales_tax_in_cents": 990
    },
    "relationships": {
      "site": {
        "data": {
          "id": "123",
          "type": "sites"
        }
      }
    }
  }],
  "meta": {
    "total_pages": 1,
    "current_page": 1
  }
}
Authorizations:
Bearer
query Parameters
page[number]
number
page[size]
number

Number of documents

fields[transactions]
string

Partial attributes as specified, e.g. fields[transactions]=amount_in_cents,sales_tax_in_cents

filter[site_id]
string

Filter by site_id, for example ?filter[site_id]=111

filter[start_date]
string

Filter by start_date, for example ?filter[start_date]=2024-12-01

filter[end_date]
string

Filter by end_date, for example ?filter[end_date]=2024-12-31

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": [
    ],
  • "links": {
    }
}

/transactions/{id}

The transaction system is a critical part of Kajabi's payment infrastructure, handling all monetary operations while maintaining detailed records for accounting, reporting, and compliance purposes.

Transaction Attributes

  • action (string) - Indicate the type of transaction:
    • charge - One-time payment
    • refund - Money returned to customer
    • subscribe - New subscription
    • subscription_charge - Recurring subscription payment
    • free_purchase - $0 transaction
    • test - Test transaction
    • dispute - Disputed charge
    • subscription_update - Subscription modification
  • state (string) - The transaction's status:
    • initialized - Transaction started
    • succeeded - Transaction completed successfully
    • failed - Transaction failed
  • payment_type (string) - Indicates the payment structure (nullable)
  • amount_in_cents (integer) - The USD price in cents (for precise decimal handling) can be negative for refunds
  • sales_tax_in_cents (integer) - The USD sales tax in cents (for precise decimal handling)
  • currency (string) - String representing the currency code (nullable) automatically upcased
    • Defaults to "USD" if not specified
  • currency_symbol (string) - String representing the currency symbol (nullable)
    • Example: "$" for USD
  • formatted_amount (string) - String representing the amount in a human-readable format
    • Includes currency symbol
    • Does not include currency code
    • Example: "$19.99"
  • created_at (string) - The creation date and time, ISO date string format (read-only)

Sparse Fields

Use the fields[transactions] parameter to request only specific attributes:

Only return amount_in_cents and sales_tax_in_cents attributes

  • GET /v1/transactions/123?fields[transactions]=amount_in_cents,sales_tax_in_cents

Response will only include requested fields

{
  "data": {
    "id": "123",
    "type": "transactions",
    "attributes": {
      "amount_in_cents": 9900,
      "sales_tax_in_cents": 990
    }
  }
}

Include Relationships

Use the include parameter to include related resources:

Include customer and offer relationships

  • GET /v1/transactions/123?include=customer,offer

Response will include related resources

{
  "data": {
    "id": "123",
    "type": "transactions",
    "attributes": {
      "action": "subscription_charge",
      "state": "succeeded",
      "payment_type": "subscription",
      "amount_in_cents": 100,
      "sales_tax_in_cents": 0,
      "currency": "USD",
      "currency_symbol": "$",
      "formatted_amount": "$1.00",
      "created_at": "2025-03-14T19:17:38.000Z"
    },
    "relationships": {
      "customer": {
        "data": {
          "id": "456",
          "type": "customers"
        }
      },
      "offer": {
        "data": {
          "id": "789",
          "type": "offers"
        }
      }
    }
  },
  "included": [
    {
      "id": "456",
      "type": "customers",
      "attributes": {
        "name": "John Doe"
        "email": "[email protected]",
        "avatar": "https://example.com/avatar.jpg",
        "external_user_id": "123",
        "public_bio": "Public Bio",
        "public_location": "Public Location",
        "public_website": "https://example.com",
        "socials": {
          "twitter": "https://twitter.com",
          "facebook": "https://facebook.com",
          "linkedin": "https://linkedin.com"
        },
        "net_revenue": 10000,
        "sign_in_count": 10,
        "last_request_at": "2024-01-15T10:30:00Z",
        "bounced_at": "2024-01-15T10:30:00Z",
        "created_at": "2024-01-15T10:30:00Z",
        "updated_at": "2024-01-15T10:30:00Z"
      }
    },
    {
      "id": "789",
      "type": "offers",
      "attributes": {
        "title": "Offer Title",
        "description": "Offer Description",
        "internal_title": "Internal Title",
        "price_in_cents": 9900,
        "payment_type": "payment_method",
        "token": "offer_token",
        "payment_method": "payment_method",
        "price_description": "Price Description",
        "checkout_url": "https://example.com/checkout",
        "recurring_offer": true,
        "subscription": true,
        "one_time": false,
        "single": false,
        "free": false
      }
    }
  ]
}

Using Multiple Parameters Together

You can combine sparse fields and include in a single request:

Get transaction with specific fields and included relationships

  • GET /v1/transactions/123?include=customer&fields[transactions]=amount_in_cents,sales_tax_in_cents&fields[customers]=name,email

Response will include transaction with only requested fields and included customer with only name and email fields

{
  "data": {
    "id": "123",
    "type": "transactions",
    "attributes": {
      "amount_in_cents": 9900,
      "sales_tax_in_cents": 990
    },
    "relationships": {}
  },
  "included": [
    {
      "id": "456",
      "type": "customers",
      "attributes": {
        "name": "John Doe"
        "email": "[email protected]"
      }
    }
  ]
}
Authorizations:
Bearer
path Parameters
id
required
string
query Parameters
fields[transactions]
string

Partial attributes as specified, e.g. fields[transactions]=amount_in_cents,sales_tax_in_cents

include
string

Load the related resources, for example ?include=customer,offer

Responses

Response samples

Content type
application/vnd.api+json
{
  • "data": {
    },
  • "links": {
    }
}

Version

/version

Returns the current version of the Kajabi API and links to the API documentation.

This endpoint does not require authentication; it can be used as a health check.

Response attributes

  • meta (object) - Meta information about the API.
    • title (string) - The title of the API.
    • version (string) - The version of the API.
  • links (object) - Links to the API documentation.
    • documentation (string) - The URL to the API documentation.
  • jsonapi (object) - JSON API information.
    • version (string) - The version of the JSON API.
    • specficiation (string) - The URL to the JSON API specification.

Responses

Response samples

Content type
application/vnd.api+json
{
  • "meta": {
    },
  • "links": {
    },
  • "jsonapi": {
    }
}