Update Mango
Partially updates one active Mango owned by the authenticated creator. The path mangoId is authoritative; _id is not a request field. Unknown request fields, including createChatroom, are stripped by the external v1 validation pipeline. Chat-room creation remains create-only.
Presence and clearing: Omitted top-level fields and omitted nested leaves preserve their stored values. false and 0 are real replacements. Arrays such as coverContents replace atomically, so [] clears the list. Nullable per-currency prices, pricing.strikeThrough, validity, trial, billing-cap, seat-limit, and seat-label fields accept null to clear. Titles, descriptions, arrays, type/frequency, base price, settings booleans, access.startsAt, and access.allowMultipleQuantity do not accept null. Provide at most one of description and descriptionHtml; either supplied form updates both returned representations.
Immutable fields: Mango type and access.startsAt are immutable. For recurring Mangoes, recurringType, base price, per-currency prices, currency, settings.includeGST, and settings.priceIncludesGST are also immutable because payment mandates already exist. These fields may be included for round-tripping only when equal to the current detail. One-time price, differential pricing, GST configuration, and strike-through pricing remain editable.
Merged validation: The API validates the resulting full Mango before any mutation. This includes coupon compatibility, creator feature entitlements, payment-mode conflicts and reset requirements, type-specific fields, relationship ownership/sharing, offshore postal-field retention, media URLs, and a new seat limit against the live active-subscriber count.
Effects and retries: Actual title changes update the room title and slug; actual intro-video changes queue thumbnail generation; an explicitly changed one-time price notifies a shared funnel; only newly added video covers are submitted for transcoding; and badge caches are invalidated only for an actual persisted change. Durable submissions are awaited, but downstream processing is asynchronous. The workflow intentionally preserves the legacy non-transactional boundary: a provider failure can occur after an earlier effect and before Mango persistence. There is no idempotency key, revision token, or transaction, so concurrent updates are last-write-wins and a retry after partial failure can repeat an earlier effect.
Authorization
bearer In: header
Path Parameters
The 24-character hexadecimal ID of the owned Mango addressed by this operation. Obtain it from List Mangoes or the result._id returned by Create Mango.
Header Parameters
Host name of the dashboard, ex: mydomain.tagmango.com
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X PATCH "https://api-prod-new.tagmango.com/api/v1/external/mangos/6a8ec3908384d1f9507e7c2c" \ -H "x-whitelabel-host: string" \ -H "Content-Type: application/json" \ -d '{ "access": { "seatLimit": null }, "differentialPricing": { "usd": 15 }, "price": 1199, "settings": { "includeGST": true, "priceIncludesGST": true } }'{
"code": 200,
"result": {
"_id": "66a1390268a76f2f5c9f39a3",
"creator": "77b2390268a76f2f5c9f39a4",
"title": "Premium Fitness Course",
"description": "A 12-week fitness transformation program.",
"descriptionHtml": "<p>A <strong>12-week</strong> fitness transformation program.</p>",
"price": 1180,
"currency": "INR",
"inrAmount": 999,
"usdAmount": 12,
"eurAmount": 11,
"isDeleted": false,
"isHidden": false,
"recurringType": "onetime",
"isPublic": true,
"isFree": true,
"zeroCostMango": true,
"affiliateEnabled": true,
"createdAt": "2019-08-24T14:15:22Z",
"updatedAt": "2019-08-24T14:15:22Z",
"coverContents": [
"https://cdn.example.com/cover.webp"
],
"checkoutLink": "https://creator.example.com/web/checkout/66a1390268a76f2f5c9f39a3?purchaseNow=true",
"shortLink": "https://creator.example.com/l/premium-fitness",
"type": "onetime",
"differentialPricing": {
"inr": 999,
"usd": 12,
"eur": 11
},
"settings": {
"includeGST": false,
"priceIncludesGST": false,
"otpless": false,
"showTdsField": false
},
"pricing": {
"strikeThrough": {
"inr": 1499,
"usd": 18,
"eur": 16
}
},
"access": {
"startsAt": "2026-09-01T10:00:00.000Z",
"validityDays": 365,
"trialDays": 7,
"maxBillingCycles": 12,
"seatLimit": 100,
"seatLabel": "Seats remaining",
"allowMultipleQuantity": false
}
},
"type": "Success",
"message": "Mango fetched successfully",
"statusMessage": "OK",
"success": true
}{
"code": 400,
"type": "Bad Request",
"statusMessage": "BAD_REQUEST",
"errorCode": "REMOTE_MEDIA_TOO_MANY_ITEMS",
"message": "A request may contain at most 10 remote Mango media items.",
"result": "A request may contain at most 10 remote Mango media items.",
"success": false
}{
"code": 401,
"type": "Unauthorized",
"statusMessage": "UNAUTHORIZED",
"message": "Invalid token",
"result": "Invalid token",
"success": false
}{
"code": 403,
"type": "Forbidden",
"statusMessage": "FORBIDDEN",
"errorCode": "WORKSHOP_MANGO_FORBIDDEN",
"message": "You can not access this api with a TagMango account, only available for whitelabel hosts",
"result": "You can not access this api with a TagMango account, only available for whitelabel hosts",
"success": false
}{
"code": 404,
"type": "Not Found",
"statusMessage": "NOT_FOUND",
"errorCode": "MANGO_NOT_FOUND",
"message": "No active Mango owned by the authenticated creator matches `mangoId`. Missing, deleted, and foreign Mangoes intentionally share this response.",
"result": "No active Mango owned by the authenticated creator matches `mangoId`. Missing, deleted, and foreign Mangoes intentionally share this response.",
"success": false
}{
"code": 409,
"type": "Conflict",
"statusMessage": "CONFLICT",
"errorCode": "IMPACTED_COUPONS_FOUND",
"message": "One or more active creator coupons exceed the Mango price.",
"result": "One or more active creator coupons exceed the Mango price.",
"success": false
}{
"code": 429,
"type": "Too Many Requests",
"statusMessage": "TOO_MANY_REQUESTS",
"message": "Request limit exceeded. try after 10 seconds",
"result": "Request limit exceeded. try after 10 seconds",
"success": false
}