Get Visible Alternate Purchase Path
Learner-facing read. Returns the first visible entry after suppression rules, or null.
Returns the first alternate purchase path a learner should see on a content item, or
null when every entry is suppressed. Visibility is evaluated server-side. This
endpoint never returns the full admin list.
Entries are considered in displayOrder ascending, then createdAt ascending. The
first entry that survives every rule is returned.
This route is AuthLevel.OPTIONAL_AUTH — it is evaluated on every content-item page
view, including for logged-out visitors, and never returns 401 for a missing
credential. An anonymous (logged-out) caller has no learner enrollment, so the response
is always { "data": null }. A company API key is likewise accepted but always yields
null: the synthetic API-key principal is apikey:company:{companyId} — not a UUID —
so the handler returns { "data": null } rather than evaluating enrollment. To see a
real CTA, call this with a learner session.
https://example.thoughtindustries.com/v3/content/:contentId/alternate-purchase-pathThis endpoint is served by the v3 API. Its full path is
https://{instance}.thoughtindustries.com/v3/content/{contentId}/alternate-purchase-path(singularalternate-purchase-path), not the/incoming/v2base URL used by the rest of this reference. Use the full URL shown in the examples below.
Example request
curl "https://{instance}.thoughtindustries.com/v3/content/3a131ac3-1a74-420d-b4da-ae10b18b2c68/alternate-purchase-path" \
-H 'Authorization: Bearer YOUR_API_KEY'Parameters
No authentication is required (OPTIONAL_AUTH). A logged-out visitor or a company API
key is accepted but always resolves to { "data": null } (see above); a real CTA
requires a learner session. There is no settings.alternatePurchasePaths check on this
route.
| Name | Type | Required | Location | Description |
|---|---|---|---|---|
contentId | uuid | Yes | path | Source course UUID. A non-UUID value returns { "data": null }, not 404. |
Suppression rules
Evaluated in this order. An earlier match short-circuits the rest.
- Rule 1 (global) — the learner already owns the source course. The whole
response is
null. - Rule 4 (global) — the learner is on a panorama client whose ecommerce is
off. The whole response is
null. - Rule 2 (per entry) — the learner already has access to everything the
ti_itemtarget grants. - Rule 3 (per entry) — the
ti_itemtarget is missing, unpublished, or has no active price. - Rule 5 (per entry) — in a panorama context, the target is not in the panorama's purchasable set (by content ID or tag).
External-URL entries skip rules 2, 3, and 5. "Owns" on rules 1 and 2 is true enrollment or entitlement — it excludes panorama-purchasable catalog, which rules 4 and 5 handle.
A non-UUID contentId, or a course with no live entries, also returns null.
Example response — visible entry
Note the data wrapper — v3 endpoints nest their payload under data. This DTO is
learner-scoped: it omits the admin object's courseId, displayOrder, and timestamps,
and adds targetTitle and targetHref (the resolved display name and link for the CTA).
{
"data": {
"id": "443d8182-d461-4568-a777-918ca729fd85",
"label": "Subscribe for unlimited access",
"targetType": "ti_item",
"targetId": "7a6b5c4d-3e2f-1a0b-9c8d-7e6f5a4b3c2d",
"targetUrl": null,
"targetUrlTitle": null,
"targetTitle": "All-Access Annual Subscription",
"targetHref": "/bundles/all-access-annual",
"hidePrimaryCta": false
}
}Example response — suppressed
{
"data": null
}Treat data: null as "do not render a secondary CTA." The response does not say
which rule fired.
Response fields
| Field | Type | Description |
|---|---|---|
data | object | null | Visible entry, or null. |
data.id | uuid | Entry ID. |
data.label | string | Sanitized CTA label. |
data.targetType | string | ti_item or external_url. |
data.targetId | uuid | null | Target TI item UUID. |
data.targetUrl | string | null | Target URL. |
data.targetUrlTitle | string | null | Display title for an external URL. |
data.targetTitle | string | null | Card title for the CTA: the linked item's name for ti_item, or the admin display title for external_url. null when unavailable. |
data.targetHref | string | null | Final CTA link: the external URL for external_url, or the resolved catalog detail-page path for ti_item (/courses/{slug}, /learning-paths/{slug}, /bundles/{slug}, /collections/{slug}). null when a ti_item target's detail page can't be resolved. |
data.hidePrimaryCta | boolean | Whether to hide the primary purchase CTA. |
Errors
An OPTIONAL_AUTH route: a missing credential is not an error — the request proceeds
anonymously and returns { "data": null }. Only a malformed/invalid credential returns
401 with code: "UNAUTHENTICATED". This route never returns 404 for an unknown
course — it returns { "data": null }.
Rate limit
This endpoint has no per-endpoint rate limiter.
Configure entries with the admin list, create, and bulk replace endpoints.