curl --request POST \
--url https://api.letsdothis.com/v0/membership-policies/{policyId}/offering-change \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'idempotency-key: <idempotency-key>' \
--data '
{
"toOfferingId": "<string>"
}
'const options = {
method: 'POST',
headers: {
'idempotency-key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({toOfferingId: '<string>'})
};
fetch('https://api.letsdothis.com/v0/membership-policies/{policyId}/offering-change', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.letsdothis.com/v0/membership-policies/{policyId}/offering-change"
payload = { "toOfferingId": "<string>" }
headers = {
"idempotency-key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"policyChangeId": "<string>",
"state": "ACCEPTED",
"effectiveAt": "2023-11-07T05:31:56Z",
"payment": {
"amountDue": {
"value": 123,
"currencyCode": "<string>"
},
"payBy": "2023-11-07T05:31:56Z",
"status": "PAID",
"reason": "BILLING_SCOPE_NOT_GRANTED",
"url": "<string>"
}
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}Change a policy's offering
Moves the policy to another offering in its scheme, now or from a renewal. Send an Idempotency-Key header, unique per change you mean to make, and the same one on a retry: a retry answers with the change the first request made, and reusing a key for a different change returns 422 MEMBERSHIP_IDEMPOTENCY_KEY_REUSED. With an organizer key the change is made by your organization: member rules and the notice period don’t apply and nothing is charged. With a member token only the primary member may ask, the scheme’s member rules and notice period apply, and an upgrade made NOW may owe the difference: payment then says what is due and by when. A token with the memberships:billing scope has the member’s saved card charged straight away (status PAID). Without that scope, or when the card needs the member’s bank to confirm it, is declined or there is none, status is ACTION_REQUIRED with a reason, and url is our page where the signed-in member finishes paying; the change applies once it is paid. Send returnUrl, on the origin of one of your app’s redirect URIs or in the same custom scheme and host, and that page sends the member back to it afterwards with policyChangeId and outcome (paid, failed or expired) added to its query. returnUrl is refused for an organizer key. A refused change returns 409 MEMBERSHIP_OFFERING_CHANGE_REFUSED with reasons. Returns 503 MEMBERSHIP_OFFERING_CHANGES_UNAVAILABLE while offering changes are switched off; retry later.
curl --request POST \
--url https://api.letsdothis.com/v0/membership-policies/{policyId}/offering-change \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'idempotency-key: <idempotency-key>' \
--data '
{
"toOfferingId": "<string>"
}
'const options = {
method: 'POST',
headers: {
'idempotency-key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({toOfferingId: '<string>'})
};
fetch('https://api.letsdothis.com/v0/membership-policies/{policyId}/offering-change', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.letsdothis.com/v0/membership-policies/{policyId}/offering-change"
payload = { "toOfferingId": "<string>" }
headers = {
"idempotency-key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"policyChangeId": "<string>",
"state": "ACCEPTED",
"effectiveAt": "2023-11-07T05:31:56Z",
"payment": {
"amountDue": {
"value": 123,
"currencyCode": "<string>"
},
"payBy": "2023-11-07T05:31:56Z",
"status": "PAID",
"reason": "BILLING_SCOPE_NOT_GRANTED",
"url": "<string>"
}
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}{
"code": "MEMBERSHIP_RESOURCE_NOT_FOUND",
"statusCode": 123,
"message": "<string>",
"reasons": [
"<string>"
]
}Authorizations
Headers
Body
Member tokens only: where our payment page sends the member once they have paid, failed to or run out of time, with policyChangeId and outcome (paid, failed or expired) added to its query. It must be on the origin of one of your app's redirect URIs, or use the same custom scheme and host.
Response
Default Response
Was this page helpful?

