Skip to content
cursareDocs
Sign inGet started
Documentation
  • Overview
  • Index2
  • Organization17
  • Sales6
  • Insights8
  • Reports and safety7
  • Minor accounts8
  • Minor safety3
  • Offers11
  • Media1
  • Contents10
  • Learner delivery1
  • Learner runtime5
  • Learners12
  • Cohorts12
  • Intake forms5
  • Campaigns4
  • Teams8
  • Affiliates7
  • Links7
  • Reviews1
  • Integrations26
  • MCP2
  • Webhooks6

Offers

Sellable packages, prices, delivery and enrollment terms.

11 endpoints

Review an offer for minor access

PUT/offers/{id}/minor-review

Path parameters

idstring

Offer id.

Request body

eligiblebooleanrequired
minimumAgeBandenum | null

under_1212_1516_17

Responses

200Review an offer for minor access.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id}/minor-review \
  --request PUT \
  --header 'Authorization: Bearer cr_live_…' \
  --header 'Content-Type: application/json' \
  --data '{
  "eligible": true,
  "minimumAgeBand": "under_12"
}'
{
  "data": {
    "eligible": true,
    "minimumAgeBand": "under_12",
    "reviewedAt": "2026-01-31T12:00:00.000Z",
    "reviewedBy": "string",
    "reviewVersion": "string"
  }
}

List the organization's offers

GET/offers

Every offer across the org's courses, grouped by course (primary offer first), each with its course's slug/title/published state. Archived offers are excluded unless includeArchived=true.

Query parameters

includeArchivedenum

Include archived offers.

truefalse

Responses

200List the organization's offers.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers \
  --header 'Authorization: Bearer cr_live_…'
{
  "data": [
    {
      "accessDurationDays": 0,
      "accessLinkActive": true,
      "accessLinkExpiresAt": "2026-01-31T12:00:00.000Z",
      "accessMode": "public",
      "affiliateCommissionBps": 0,
      "allowedEmailDomains": [
        "string"
      ],
      "autoCreateCohort": true,
      "cohortDurationDays": 0,
      "cohortEnrollmentWindowDays": 0,
      "cohortTutorId": "string",
      "contentId": "string",
      "contentPublished": true,
      "contentSlug": "string",
      "contentTitle": "string",
      "createdAt": "2026-01-31T12:00:00.000Z",
      "currency": "string",
      "defaultCohortSeatLimit": 0,
      "deliveryMode": "self_paced",
      "discussionEnabled": true,
      "id": "string",
      "installments": 0,
      "intakeFormId": "string",
      "isPrimary": true,
      "listed": true,
      "minorEligible": true,
      "minorMinimumAgeBand": "under_12",
      "minorReviewedAt": "2026-01-31T12:00:00.000Z",
      "minorReviewVersion": "string",
      "name": "string",
      "price": 0,
      "requiresApproval": true,
      "seatLimit": 0,
      "status": "active",
      "updatedAt": "2026-01-31T12:00:00.000Z",
      "withdrawalDays": 0
    }
  ]
}

List a content's offers

GET/contents/{id}/offers

The sellable offers of one course, primary first. Archived excluded unless includeArchived=true.

Path parameters

idstring

The content id.

Query parameters

includeArchivedenum

truefalse

Responses

200List a content's offers.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/contents/{id}/offers \
  --header 'Authorization: Bearer cr_live_…'
{
  "data": [
    {
      "accessDurationDays": 0,
      "accessLinkActive": true,
      "accessLinkExpiresAt": "2026-01-31T12:00:00.000Z",
      "accessMode": "public",
      "affiliateCommissionBps": 0,
      "allowedEmailDomains": [
        "string"
      ],
      "autoCreateCohort": true,
      "cohortDurationDays": 0,
      "cohortEnrollmentWindowDays": 0,
      "cohortTutorId": "string",
      "contentId": "string",
      "createdAt": "2026-01-31T12:00:00.000Z",
      "currency": "string",
      "defaultCohortSeatLimit": 0,
      "deliveryMode": "self_paced",
      "discussionEnabled": true,
      "id": "string",
      "installments": 0,
      "intakeFormId": "string",
      "isPrimary": true,
      "listed": true,
      "minorEligible": true,
      "minorMinimumAgeBand": "under_12",
      "minorReviewedAt": "2026-01-31T12:00:00.000Z",
      "minorReviewVersion": "string",
      "name": "string",
      "price": 0,
      "requiresApproval": true,
      "seatLimit": 0,
      "status": "active",
      "updatedAt": "2026-01-31T12:00:00.000Z",
      "withdrawalDays": 0
    }
  ]
}

Create an offer

POST/contents/{id}/offers

Add a non-primary sellable offer to a course. It must share the course's currency (free and paid offers may coexist); a priced offer needs a connected payment account.

Path parameters

idstring

The content id.

Request body

currencystringrequired
namestringrequired
priceinteger | nullrequired
accessDurationDaysinteger | null
accessModeenum

publicemail_domainprivate_linkemail_domain_or_link

affiliateCommissionBpsinteger
allowedEmailDomainsstring[]
autoCreateCohortboolean
cohortDurationDaysinteger | null
cohortEnrollmentWindowDaysinteger | null

Days after start that a new automatic cohort accepts later learners. Null = until cohort end; 0 = founding enrollment only.

cohortTutorIdstring | null
defaultCohortSeatLimitinteger | null
deliveryModeenum

self_pacedcohort

discussionEnabledboolean
installmentsinteger | null
intakeFormIdstring | null
listedboolean
requiresApprovalboolean
seatLimitinteger | null
withdrawalDaysnumber | number | number | number

Responses

201Create an offer.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/contents/{id}/offers \
  --request POST \
  --header 'Authorization: Bearer cr_live_…' \
  --header 'Content-Type: application/json' \
  --data '{
  "currency": "string",
  "name": "string",
  "price": 0,
  "accessDurationDays": 0,
  "accessMode": "public",
  "affiliateCommissionBps": 0,
  "allowedEmailDomains": [
    "string"
  ],
  "autoCreateCohort": true,
  "cohortDurationDays": 0,
  "cohortEnrollmentWindowDays": 0,
  "cohortTutorId": "string",
  "defaultCohortSeatLimit": 0,
  "deliveryMode": "self_paced",
  "discussionEnabled": true,
  "installments": 0,
  "intakeFormId": "string",
  "listed": true,
  "requiresApproval": true,
  "seatLimit": 0,
  "withdrawalDays": 0
}'
{
  "data": {
    "accessDurationDays": 0,
    "accessLinkActive": true,
    "accessLinkExpiresAt": "2026-01-31T12:00:00.000Z",
    "accessMode": "public",
    "affiliateCommissionBps": 0,
    "allowedEmailDomains": [
      "string"
    ],
    "autoCreateCohort": true,
    "cohortDurationDays": 0,
    "cohortEnrollmentWindowDays": 0,
    "cohortTutorId": "string",
    "contentId": "string",
    "createdAt": "2026-01-31T12:00:00.000Z",
    "currency": "string",
    "defaultCohortSeatLimit": 0,
    "deliveryMode": "self_paced",
    "discussionEnabled": true,
    "id": "string",
    "installments": 0,
    "intakeFormId": "string",
    "isPrimary": true,
    "listed": true,
    "minorEligible": true,
    "minorMinimumAgeBand": "under_12",
    "minorReviewedAt": "2026-01-31T12:00:00.000Z",
    "minorReviewVersion": "string",
    "name": "string",
    "price": 0,
    "requiresApproval": true,
    "seatLimit": 0,
    "status": "active",
    "updatedAt": "2026-01-31T12:00:00.000Z",
    "withdrawalDays": 0
  }
}

Get an offer

GET/offers/{id}

One offer with its live seat usage and enrollment counts.

Path parameters

idstring

The offer id.

Responses

200Get an offer.
401Missing, invalid or revoked API key.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id} \
  --header 'Authorization: Bearer cr_live_…'
{
  "data": {
    "accessDurationDays": 0,
    "accessLinkActive": true,
    "accessLinkExpiresAt": "2026-01-31T12:00:00.000Z",
    "accessMode": "public",
    "affiliateCommissionBps": 0,
    "allowedEmailDomains": [
      "string"
    ],
    "autoCreateCohort": true,
    "cohortDurationDays": 0,
    "cohortEnrollmentWindowDays": 0,
    "cohortTutorId": "string",
    "contentId": "string",
    "createdAt": "2026-01-31T12:00:00.000Z",
    "currency": "string",
    "defaultCohortSeatLimit": 0,
    "deliveryMode": "self_paced",
    "discussionEnabled": true,
    "enrollment": {
      "learners": 0,
      "pendingRequests": 0
    },
    "id": "string",
    "installments": 0,
    "intakeFormId": "string",
    "isPrimary": true,
    "listed": true,
    "minorEligible": true,
    "minorMinimumAgeBand": "under_12",
    "minorReviewedAt": "2026-01-31T12:00:00.000Z",
    "minorReviewVersion": "string",
    "name": "string",
    "price": 0,
    "requiresApproval": true,
    "seatLimit": 0,
    "seats": {
      "full": true,
      "limit": 0,
      "used": 0
    },
    "status": "active",
    "updatedAt": "2026-01-31T12:00:00.000Z",
    "withdrawalDays": 0
  }
}

Update an offer

PATCH/offers/{id}

Patch any subset of an offer's commerce/format/enrollment fields. Currency changes must keep the course's active offers on one currency; going paid needs a payment account.

Path parameters

idstring

The offer id.

Request body

accessDurationDaysinteger | null
accessModeenum

publicemail_domainprivate_linkemail_domain_or_link

affiliateCommissionBpsinteger
allowedEmailDomainsstring[]
autoCreateCohortboolean
cohortDurationDaysinteger | null
cohortEnrollmentWindowDaysinteger | null

Days after start that a new automatic cohort accepts later learners. Null = until cohort end; 0 = founding enrollment only.

cohortTutorIdstring | null
currencystring
defaultCohortSeatLimitinteger | null
deliveryModeenum

self_pacedcohort

discussionEnabledboolean
installmentsinteger | null
intakeFormIdstring | null
listedboolean
namestring
priceinteger | null
requiresApprovalboolean
seatLimitinteger | null
withdrawalDaysnumber | number | number | number

Responses

200Update an offer.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id} \
  --request PATCH \
  --header 'Authorization: Bearer cr_live_…' \
  --header 'Content-Type: application/json' \
  --data '{
  "accessDurationDays": 0,
  "accessMode": "public",
  "affiliateCommissionBps": 0,
  "allowedEmailDomains": [
    "string"
  ],
  "autoCreateCohort": true,
  "cohortDurationDays": 0,
  "cohortEnrollmentWindowDays": 0,
  "cohortTutorId": "string",
  "currency": "string",
  "defaultCohortSeatLimit": 0,
  "deliveryMode": "self_paced",
  "discussionEnabled": true,
  "installments": 0,
  "intakeFormId": "string",
  "listed": true,
  "name": "string",
  "price": 0,
  "requiresApproval": true,
  "seatLimit": 0,
  "withdrawalDays": 0
}'
{
  "data": {
    "accessDurationDays": 0,
    "accessLinkActive": true,
    "accessLinkExpiresAt": "2026-01-31T12:00:00.000Z",
    "accessMode": "public",
    "affiliateCommissionBps": 0,
    "allowedEmailDomains": [
      "string"
    ],
    "autoCreateCohort": true,
    "cohortDurationDays": 0,
    "cohortEnrollmentWindowDays": 0,
    "cohortTutorId": "string",
    "contentId": "string",
    "createdAt": "2026-01-31T12:00:00.000Z",
    "currency": "string",
    "defaultCohortSeatLimit": 0,
    "deliveryMode": "self_paced",
    "discussionEnabled": true,
    "id": "string",
    "installments": 0,
    "intakeFormId": "string",
    "isPrimary": true,
    "listed": true,
    "minorEligible": true,
    "minorMinimumAgeBand": "under_12",
    "minorReviewedAt": "2026-01-31T12:00:00.000Z",
    "minorReviewVersion": "string",
    "name": "string",
    "price": 0,
    "requiresApproval": true,
    "seatLimit": 0,
    "status": "active",
    "updatedAt": "2026-01-31T12:00:00.000Z",
    "withdrawalDays": 0
  }
}

Generate or rotate a private offer link

POST/offers/{id}/access-link

Returns a new bearer secret once and immediately invalidates the previous link. The offer must use private_link or email_domain_or_link access.

Path parameters

idstring

The offer id.

Request body

expiresInDaysnumber | number | number | any | null

Automatic expiry. Null keeps the link valid until explicitly revoked.

Responses

200Generate or rotate a private offer link.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id}/access-link \
  --request POST \
  --header 'Authorization: Bearer cr_live_…' \
  --header 'Content-Type: application/json' \
  --data '{
  "expiresInDays": 30
}'
{
  "data": {
    "expiresAt": "2026-01-31T12:00:00.000Z",
    "token": "string"
  }
}

Revoke a private offer link

DELETE/offers/{id}/access-link

Immediately invalidates the offer's current bearer link.

Path parameters

idstring

The offer id.

Responses

200Revoke a private offer link.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id}/access-link \
  --request DELETE \
  --header 'Authorization: Bearer cr_live_…'
{
  "data": {
    "id": "string",
    "revoked": true
  }
}

Duplicate an offer

POST/offers/{id}/duplicate

Copy reusable terms into a new active, non-primary, unlisted offer. Credentials and history are never copied.

Path parameters

idstring

The offer id.

Request body

namestring

Name for the copied offer.

Responses

201Duplicate an offer.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id}/duplicate \
  --request POST \
  --header 'Authorization: Bearer cr_live_…' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "string"
}'
{
  "data": {
    "accessDurationDays": 0,
    "accessLinkActive": true,
    "accessLinkExpiresAt": "2026-01-31T12:00:00.000Z",
    "accessMode": "public",
    "affiliateCommissionBps": 0,
    "allowedEmailDomains": [
      "string"
    ],
    "autoCreateCohort": true,
    "cohortDurationDays": 0,
    "cohortEnrollmentWindowDays": 0,
    "cohortTutorId": "string",
    "contentId": "string",
    "createdAt": "2026-01-31T12:00:00.000Z",
    "currency": "string",
    "defaultCohortSeatLimit": 0,
    "deliveryMode": "self_paced",
    "discussionEnabled": true,
    "id": "string",
    "installments": 0,
    "intakeFormId": "string",
    "isPrimary": true,
    "listed": true,
    "minorEligible": true,
    "minorMinimumAgeBand": "under_12",
    "minorReviewedAt": "2026-01-31T12:00:00.000Z",
    "minorReviewVersion": "string",
    "name": "string",
    "price": 0,
    "requiresApproval": true,
    "seatLimit": 0,
    "status": "active",
    "updatedAt": "2026-01-31T12:00:00.000Z",
    "withdrawalDays": 0
  }
}

Make an offer primary

POST/offers/{id}/set-primary

Promote an active offer to the course's canonical enrollment option.

Path parameters

idstring

The offer id.

Responses

200Make an offer primary.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id}/set-primary \
  --request POST \
  --header 'Authorization: Bearer cr_live_…'
{
  "data": {
    "id": "string",
    "isPrimary": true
  }
}

Archive an offer

POST/offers/{id}/archive

Retire an offer (it stops selling; its sales and learners are kept). The primary offer can't be archived.

Path parameters

idstring

The offer id.

Responses

200Archive an offer.
400Validation failed or the request body is malformed.
401Missing, invalid or revoked API key.
403The key's organization does not own this resource.
404The resource does not exist (or belongs to another org).
429Rate limit exceeded (240 reads/min, 60 writes/min per key).
500Unexpected server error.
curl https://api.cursare.com/v1/offers/{id}/archive \
  --request POST \
  --header 'Authorization: Bearer cr_live_…'
{
  "data": {
    "id": "string",
    "status": "string"
  }
}

Your privacy choices

The technical Tag Manager container is required to apply your choices. Analytics and marketing cookies and storage remain optional and stay off until you authorize them. Privacy Policy.

Sign-in, security, core functions and consent enforcement.

Audience measurement such as Google Analytics.

Marketing storage, campaign attribution and optional tags.