curl --request PATCH \
--url https://api.tassyir.io/apps/2026-10/offers/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expectedVersion": 2,
"title": "<string>",
"label": {},
"config": {},
"combinesWith": {},
"eligibility": {},
"totalUsageLimit": 2,
"perBuyerLimit": 2,
"startsAt": "<string>",
"endsAt": "<string>",
"targets": [
{
"refId": "<string>"
}
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
expectedVersion: 2,
title: '<string>',
label: {},
config: {},
combinesWith: {},
eligibility: {},
totalUsageLimit: 2,
perBuyerLimit: 2,
startsAt: '<string>',
endsAt: '<string>',
targets: [{refId: '<string>'}]
})
};
fetch('https://api.tassyir.io/apps/2026-10/offers/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"id": "<string>",
"storeId": "<string>",
"kind": "<string>",
"method": "<string>",
"title": "<string>",
"label": {
"ar": "<string>",
"fr": "<string>",
"en": "<string>"
},
"status": "<string>",
"currency": "<string>",
"quantity": {
"priceMode": "<string>",
"tiers": [
{
"pieces": 0,
"label": {
"ar": "<string>",
"fr": "<string>",
"en": "<string>"
},
"total": "<string>",
"percentOff": 123,
"amountOffEach": "<string>",
"preselected": true,
"freeDelivery": true
}
]
},
"freeDelivery": {
"thresholdKind": "<string>",
"thresholdPieces": 0,
"thresholdAmount": "<string>",
"delivery": "<string>",
"wilayas": [
"<string>"
]
},
"productDiscount": {
"valueType": "<string>",
"percent": 123,
"amount": "<string>",
"maxAmount": "<string>",
"showCountdown": true
},
"orderDiscount": {
"valueType": "<string>",
"percent": 123,
"amount": "<string>",
"maxAmount": "<string>",
"minimumKind": "<string>",
"minimumPieces": 0,
"minimumAmount": "<string>"
},
"bxgy": {
"buyPieces": 0,
"getPieces": 0,
"getDiscountType": "<string>",
"getPercent": 123,
"getPrice": "<string>",
"maxPerOrder": 0
},
"addon": {
"priceType": "<string>",
"price": "<string>",
"percent": 123,
"amountOff": "<string>",
"maxQuantity": 0,
"beforeSubmit": true,
"afterSubmit": true
},
"appRule": {
"typeHandle": "<string>",
"rule": "<unknown>"
},
"combinesWith": {
"product": true,
"order": true,
"delivery": true
},
"eligibility": {
"audience": "<string>",
"channels": [
"<string>"
],
"wilayas": [
"<string>"
],
"deliveryMethods": [
"<string>"
]
},
"targets": [
{
"role": "<string>",
"type": "<string>",
"id": "<string>"
}
],
"codeCount": 0,
"totalUsageLimit": 0,
"perBuyerLimit": 0,
"startsAt": "2023-11-07T05:31:56Z",
"endsAt": "2023-11-07T05:31:56Z",
"publishedAt": "2023-11-07T05:31:56Z",
"pausedAt": "2023-11-07T05:31:56Z",
"archivedAt": "2023-11-07T05:31:56Z",
"appOwned": true,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "BAD_REQUEST",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "APP_TOKEN_INVALID",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 403,
"detail": "<string>",
"code": "OFFER_NOT_OWNED",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 404,
"detail": "<string>",
"code": "NOT_FOUND",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 409,
"detail": "<string>",
"code": "IDEMPOTENCY_KEY_IN_USE",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "PAYLOAD_TOO_LARGE",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "UNSUPPORTED_MEDIA_TYPE",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 422,
"detail": "<string>",
"code": "IDEMPOTENCY_KEY_REUSED",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 429,
"detail": "<string>",
"code": "BUSINESS_RATE_LIMITED",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 500,
"detail": "<string>",
"code": "INTERNAL_ERROR",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "API_BUSY",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}Update an offer
Changes the fields sent (targets, when sent, replaces the whole target set; kind and method never change). A live offer must stay publishable. The change applies to the offer as it is now unless expectedVersion is sent (the dashboard’s compare-and-set, 409 OFFER_VERSION_CONFLICT with currentVersion). An app changes, and reads the codes and redemptions of, only the offers its own installation created (ownerInstallationId is set from the token when it creates one). A merchant’s offer, or another app’s, is 403 OFFER_NOT_OWNED; an offer the token cannot see (another business, a store outside the installation’s stores) is 404.
Needs the write_offers scope (permission offers:update).
curl --request PATCH \
--url https://api.tassyir.io/apps/2026-10/offers/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"expectedVersion": 2,
"title": "<string>",
"label": {},
"config": {},
"combinesWith": {},
"eligibility": {},
"totalUsageLimit": 2,
"perBuyerLimit": 2,
"startsAt": "<string>",
"endsAt": "<string>",
"targets": [
{
"refId": "<string>"
}
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
expectedVersion: 2,
title: '<string>',
label: {},
config: {},
combinesWith: {},
eligibility: {},
totalUsageLimit: 2,
perBuyerLimit: 2,
startsAt: '<string>',
endsAt: '<string>',
targets: [{refId: '<string>'}]
})
};
fetch('https://api.tassyir.io/apps/2026-10/offers/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"id": "<string>",
"storeId": "<string>",
"kind": "<string>",
"method": "<string>",
"title": "<string>",
"label": {
"ar": "<string>",
"fr": "<string>",
"en": "<string>"
},
"status": "<string>",
"currency": "<string>",
"quantity": {
"priceMode": "<string>",
"tiers": [
{
"pieces": 0,
"label": {
"ar": "<string>",
"fr": "<string>",
"en": "<string>"
},
"total": "<string>",
"percentOff": 123,
"amountOffEach": "<string>",
"preselected": true,
"freeDelivery": true
}
]
},
"freeDelivery": {
"thresholdKind": "<string>",
"thresholdPieces": 0,
"thresholdAmount": "<string>",
"delivery": "<string>",
"wilayas": [
"<string>"
]
},
"productDiscount": {
"valueType": "<string>",
"percent": 123,
"amount": "<string>",
"maxAmount": "<string>",
"showCountdown": true
},
"orderDiscount": {
"valueType": "<string>",
"percent": 123,
"amount": "<string>",
"maxAmount": "<string>",
"minimumKind": "<string>",
"minimumPieces": 0,
"minimumAmount": "<string>"
},
"bxgy": {
"buyPieces": 0,
"getPieces": 0,
"getDiscountType": "<string>",
"getPercent": 123,
"getPrice": "<string>",
"maxPerOrder": 0
},
"addon": {
"priceType": "<string>",
"price": "<string>",
"percent": 123,
"amountOff": "<string>",
"maxQuantity": 0,
"beforeSubmit": true,
"afterSubmit": true
},
"appRule": {
"typeHandle": "<string>",
"rule": "<unknown>"
},
"combinesWith": {
"product": true,
"order": true,
"delivery": true
},
"eligibility": {
"audience": "<string>",
"channels": [
"<string>"
],
"wilayas": [
"<string>"
],
"deliveryMethods": [
"<string>"
]
},
"targets": [
{
"role": "<string>",
"type": "<string>",
"id": "<string>"
}
],
"codeCount": 0,
"totalUsageLimit": 0,
"perBuyerLimit": 0,
"startsAt": "2023-11-07T05:31:56Z",
"endsAt": "2023-11-07T05:31:56Z",
"publishedAt": "2023-11-07T05:31:56Z",
"pausedAt": "2023-11-07T05:31:56Z",
"archivedAt": "2023-11-07T05:31:56Z",
"appOwned": true,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "BAD_REQUEST",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "APP_TOKEN_INVALID",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 403,
"detail": "<string>",
"code": "OFFER_NOT_OWNED",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 404,
"detail": "<string>",
"code": "NOT_FOUND",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 409,
"detail": "<string>",
"code": "IDEMPOTENCY_KEY_IN_USE",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "PAYLOAD_TOO_LARGE",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "UNSUPPORTED_MEDIA_TYPE",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 422,
"detail": "<string>",
"code": "IDEMPOTENCY_KEY_REUSED",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 429,
"detail": "<string>",
"code": "BUSINESS_RATE_LIMITED",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 500,
"detail": "<string>",
"code": "INTERNAL_ERROR",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "API_BUSY",
"docs": "<string>",
"fix": "<string>",
"requestId": "<string>",
"errors": [
"<string>"
]
}Authorizations
An app access token from POST /apps/oauth/token, valid 1 hour. An offline token acts as the app; an online token acts as the app on behalf of one dashboard user (the intersection of both permission sets).
Headers
Makes a write safe to retry: the same key with the same method, path, query and body within 24 hours answers the stored result (Idempotent-Replayed: true) without running the write again. Only a successful answer is stored, so a retry after a failure runs. A key reused for a different request is 422 IDEMPOTENCY_KEY_REUSED; one whose first request still runs is 409 IDEMPOTENCY_KEY_IN_USE.
1 - 255^[\x21-\x7E]+$Path Parameters
A resource id. One this installation cannot read, or a malformed one, is 404 NOT_FOUND.
1Query Parameters
Return only these top-level fields, separated by commas; the id is always kept. The response schema describes the whole resource. An unknown name is 400 INVALID_FIELDS. Fields: id, storeId, kind, method, title, label, status, currency, quantity, freeDelivery, productDiscount, orderDiscount, bxgy, addon, appRule, combinesWith, eligibility, targets, codeCount, totalUsageLimit, perBuyerLimit, startsAt, endsAt, publishedAt, pausedAt, archivedAt, appOwned, createdAt, updatedAt.
1000Body
x >= 1200quantity, free_delivery, product_discount, order_discount, bxgy, addon, app automatic, code Label is the offer's stored settings for its kind, exactly as the Offers page keeps them.
Config is the offer's stored settings for its kind, exactly as the Offers page keeps them.
CombinesWith is the offer's stored settings for its kind, exactly as the Offers page keeps them.
Eligibility is the offer's stored settings for its kind, exactly as the Offers page keeps them.
x >= 1x >= 14040101Show child attributes
Show child attributes
Response
The offer as it is now.
An offer (API 2026-10).
Show child attributes
Show child attributes