Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Kajabi API V1 Offers API
version: 1.1.0
description: '## Public API
* Server URL `https://api.kajabi.com`
* Endpoint paths are prefixed with `/v1`
* Version endpoint `GET https://api.kajabi.com/v1/version`
* See the Developers Site for documentation and examples.'
contact:
email: support@kajabi.com
name: Support
url: https://help.kajabi.com/hc/en-us/articles/4404549690523-How-to-Get-Help-From-Kajabi-Live-Agents
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: https://api.kajabi.com
description: Production
tags:
- name: Offers
paths:
/v1/offers:
get:
summary: List offers
description: '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:
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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
```json
{
"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"
}
}]
}
```
## 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
```json
{
"data": [
{
"id": "456",
"type"…'
tags:
- Offers
security:
- Bearer: []
parameters:
- name: sort
in: query
required: false
description: 'Sort order, use: title, price_in_cents, for descending order use ''-'' e.g. &sort=-price_in_cents'
schema:
type: string
- name: page[number]
in: query
required: false
schema:
type: number
- name: page[size]
in: query
required: false
description: Number of documents
schema:
type: number
- name: fields[offers]
in: query
required: false
description: Partial attributes as specified, e.g. fields[offers]=title,price_in_cents
schema:
type: string
- name: filter[site_id]
in: query
required: false
description: Filter by site_id, for example ?filter[site_id]=111
schema:
type: string
- name: filter[title_cont]
in: query
required: false
description: Filter by title contains, for example ?filter[title_cont]=course
schema:
type: string
- name: filter[description_cont]
in: query
required: false
description: Filter by description contains, for example ?filter[description_cont]=course
schema:
type: string
responses:
'200':
description: Success, list of offers which the current user may access
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/offers_index_response'
'401':
description: Unauthorized, Authorization header is missing or invalid
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/errors_unauthorized'
'403':
description: Forbidden, insufficient permission to access the resource
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/errors_forbidden'
operationId: getV1Offers
x-operation-id-source: derived
/v1/offers/{id}:
get:
summary: Offer details
description: '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
* `image_url` (string) - URL to the image associated with the offer (nullable)
## Include Relationships
Use the `include` parameter to include related products:
* `GET /v1/offers/123?include=products`
Response will include products relationship
```json
{
"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,
"image_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",
"image_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
```json
{
"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
```json
{
"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"
}
}
]
}
```'
tags:
- Offers
security:
- Bearer: []
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: include
in: query
required: false
description: Load the related resources, for example ?include=products
schema:
type: string
- name: fields[offers]
in: query
required: false
description: Partial attributes as specified, e.g. fields[offers]=title,price_in_cents
schema:
type: string
responses:
'200':
description: Success, shows details of an offer
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/offers_show_response'
'401':
description: Unauthorized, Authorization header is missing or invalid
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/errors_unauthorized'
'403':
description: Forbidden, insufficient permission to access the resource
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/errors_forbidden'
operationId: getV1OffersById
x-operation-id-source: derived
/v1/offers/{offer_id}/relationships/products:
get:
summary: List offer's products
description: get the offer's relationship to products, response is a list of resource identifiers
tags:
- Offers
security:
- Bearer: []
parameters:
- name: offer_id
in: path
required: true
schema:
type: string
responses:
'200':
description: Success, shows details for tags relationship
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/contacts_relationships_tags_response'
'401':
description: Unauthorized, Authorization header is missing or invalid
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/errors_unauthorized'
'403':
description: Forbidden, insufficient permission to access the resource
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/errors_forbidden'
'404':
description: Not found, the resource is unknown
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/errors_forbidden'
operationId: getV1OffersByOfferIdRelationshipsProducts
x-operation-id-source: derived
components:
schemas:
errors_attributes:
type: object
properties:
status:
type: string
source:
type:
- object
- 'null'
properties:
pointer:
type: string
title:
type: string
detail:
type: string
offers_show_response:
type: object
properties:
data:
type: object
properties:
id:
type: string
type:
type: string
attributes:
$ref: '#/components/schemas/offers_attributes'
relationships:
type: object
properties:
site:
type: object
properties:
data:
$ref: '#/components/schemas/resource_identifier'
products:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/resource_identifier'
links:
type: object
properties:
self:
type: string
current:
type: string
offers_index_response:
type: object
properties:
data:
type: array
items:
type: object
properties:
id:
type: string
type:
type: string
attributes:
$ref: '#/components/schemas/offers_attributes'
relationships:
type: object
properties:
site:
type: object
properties:
data:
$ref: '#/components/schemas/resource_identifier'
products:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/resource_identifier'
links:
type: object
properties:
self:
type: string
current:
type: string
resource_identifiers:
type: array
items:
$ref: '#/components/schemas/resource_identifier'
resource_identifier:
type: object
properties:
id:
type: string
type:
type: string
required:
- id
- type
offers_attributes:
type: object
properties:
title:
type: string
description:
type:
- string
- 'null'
internal_title:
type:
- string
- 'null'
currency:
type: string
price_in_cents:
type: integer
payment_type:
type: string
token:
type: string
payment_method:
type: string
price_description:
type: string
checkout_url:
type: string
recurring_offer:
type: boolean
subscription:
type: boolean
one_time:
type: boolean
single:
type: boolean
free:
type: boolean
image_url:
type:
- string
- 'null'
required:
- title
errors_unauthorized:
type: object
properties:
errors:
type: array
items:
$ref: '#/components/schemas/errors_attributes'
contacts_relationships_tags_response:
type: object
properties:
data:
$ref: '#/components/schemas/resource_identifiers'
links:
type: object
properties:
self:
type: string
errors_forbidden:
type: object
properties:
errors:
type: array
items:
$ref: '#/components/schemas/errors_attributes'
securitySchemes:
Bearer:
type: http
scheme: bearer
x-mint:
mcp:
enabled: true