Returning.AIDevelopers
v1

API reference / Store / Purchase History

.md

Update redemption instructions or voucher details

Change the redemption instructions, voucher code or customer details saved on one redemption order in your community.

Last updated 26 Sep 2026API v1

Method
PATCH
Path
https://api.returning.ai/v1/purchase-histories/{purchaseHistoryID}
Permission
purchase-history
Retries
No Idempotency-Key; read the order before retrying

When to use this

  • You fulfil a reward by hand and need to give the trader a new voucher code or expiry date.
  • The instructions a trader sees for one order need correcting, such as where to collect a prize.
  • A trader asks you to fix the delivery address or an order-form answer on their order.

Authentication#

Header
Authorization: Bearer <API_KEY>
Permission
purchase-historyShown in the dashboard as “Purchase History”

Send a Community API key with the purchase-history permission. The key decides the community, so you can only change orders in that community. Keep the key on your server.

Behaviour#

There are two kinds of change, and each request makes one of them.

  • Instructions and voucher. Send redemptionInstructions, the pair voucherCode and voucherExpiryDate, or all three. New instructions apply to this order only; the product keeps its own. Setting instructions also refreshes the order's saved copy of the product (name, description, image and price) from the current product, and fails with 404 if the product was deleted. A new voucher code changes the voucher record itself, and must not match another voucher on the same product.
  • Customer details. Send changes with userInfo, customOptions or both. Only values that differ from what is saved count. Each successful update adds an entry to the order's change history, and meta.auditEventId identifies it.

The order's status, price and coins don't change, and the trader isn't emailed or notified. The latest update wins if two arrive together.

Request#

Path parameters#

purchaseHistoryID#stringREQUIRED
The order ID (ORD...) from redemptionId in the order lists. The order's internal _id also works.

RuleOrder ID in your community

EgORD20269268300418273

Headers#

Authorization#stringREQUIRED
Community API key with purchase-history.

RuleBearer <API_KEY>

Content-Type#stringREQUIRED
Request body format.

Ruleapplication/json

Body#

Send a JSON object with at least one field. Fields this endpoint doesn't take are rejected, not ignored. Text values are trimmed. voucherExpiryDate is a date only, in DD/MM/YYYY; the voucher expires at the start of that day, midnight UTC, so send the day after if it should last through a date.

redemptionInstructions#stringOPTIONAL
New instructions shown to the trader for this order only. The product's own instructions don't change. Needs the product to still exist.

Rule1-10,000 chars, not blank; trimmed

Eg"Your $25 credit is added to your live trading account within 2 business days."

voucherCode#stringOPTIONAL
New voucher code for this order. Send it with voucherExpiryDate.

Rule1-512 chars, not blank; trimmed; unique within the product

Eg"TC25-8R5N-3C1Y"

voucherExpiryDate#stringOPTIONAL
New voucher expiry date. Send it with voucherCode. Saved as the start of that day, midnight UTC.

RuleDD/MM/YYYY, a real date

Eg"31/12/2026"

changes#objectOPTIONAL
Customer details and order-form answers to change. Send at least one of userInfo or customOptions, and no other top-level field.
userInfo#objectOPTIONAL
Customer details saved on the order. Each field is optional: firstName, lastName, phonePrefix, phone, country, city, state, address, postalCode. Only state can be blank. Email can't be changed.
customOptions#object[]OPTIONAL
Answers to the product's order form. Each entry names one saved field, by name or _id, never both.
name#stringOPTIONAL
The form field's name, matched ignoring capital letters. Use _id instead if two fields share a name.

Eg"Account number"

_id#stringOPTIONAL
The form field's ID, as saved on the order.
value#stringREQUIRED
The new answer. Can't be blank for a required field, and must be a number for a number field.

Eg"<brokerCustomerId>"

curl --request PATCH \
  --url https://api.returning.ai/v1/purchase-histories/ORD20269268300418273 \
  --header 'Authorization: Bearer <API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "redemptionInstructions": "Your $25 credit is added to your live trading account within 2 business days.",
    "voucherCode": "TC25-8R5N-3C1Y",
    "voucherExpiryDate": "31/12/2026"
  }'

Response#

A 200 returns the whole order in data, including the voucher code the trader sees. Branch on the HTTP status and meta.code, never on message.

meta#objectALWAYS
Status details.

Eg{ ... }

status#stringALWAYS
Result of the request.

Rulesuccess

statusCode#integerALWAYS
The HTTP status, repeated.

Eg200

code#stringALWAYS
Machine-readable result code.

RulePURCHASE_HISTORY_UPDATED

auditEventId#stringWHEN YOU SEND CHANGES
ID of the change-history entry this update created. Present only for changes updates.
message#stringALWAYS
Human-readable summary. It differs between the two kinds of change. Do not branch on it.

Eg"Update purchase history success."

data#objectALWAYS
The whole order after the change.

Eg{ ... }

_id#string
Internal record ID of the order.

Eg"66f000000000000000000401"

purchaseID#string
The order ID (ORD...).

Eg"ORD20269268300418273"

communityID#string
Your community ID.

Eg"66f000000000000000000010"

userID#string
The trader's internal record ID. This is not the platform user ID.

Eg"<userObjectId>"

status#string
The order's current status name. This call doesn't change it.
purchaseStatusID#string
ID of the order's current status.
price#number
Coins the trader paid for the order.
quantity#number
Units in the order.
voucherCode#string
The voucher code the trader sees for this order.

Eg"TC25-8R5N-3C1Y"

voucherExpiryDate#string
When that voucher expires, ISO 8601 UTC.

RuleDate-time

Eg"2026-12-31T00:00:00.000Z"

voucher#object
The voucher record assigned to the order. A voucher update changes it too.

Eg{ ... }

_id#string
Voucher ID.

Eg"66f000000000000000000502"

code#string
The voucher's code.

Eg"TC25-8R5N-3C1Y"

status#string
Voucher status.

Ruleactive, redeemed or expired

Eg"redeemed"

expiryDate#string
When the voucher expires, ISO 8601 UTC.

RuleDate-time

Eg"2026-12-31T00:00:00.000Z"

product#object
The product as saved on the order, including the order's redemptionInstructions. null when the product no longer exists and the order has no saved copy.

Eg{ ... }

_id#string
Product ID.

Eg"66f000000000000000000101"

name#string
Product name.

Eg"$25 Trading Credit"

redemptionInstructions#string
The instructions the trader sees for this order.

Eg"Your $25 credit is added to your live trading account within 2 business days."

userInfo#object
Customer details saved on the order, such as username, name, email and any address fields.
customOptions#object[]
The order-form answers, each with its _id, name and value. Empty when the product has no form.
purchasedDate#string
When the trader redeemed, ISO 8601 UTC.
refundedAt#string
When the order was refunded, ISO 8601 UTC. Present only on refunded orders.
latestStatusHistory#object
The order's most recent status change, with oldStatusName, newStatusName, remark and createdAt. Present once the status has changed.
createdAt#string
When the order was created, ISO 8601 UTC.

RuleDate-time

Eg"2026-09-26T08:30:00.000Z"

updatedAt#string
When the order last changed, ISO 8601 UTC.

RuleDate-time

Eg"2026-09-27T10:15:00.000Z"

{
  "meta": {
    "status": "success",
    "statusCode": 200,
    "code": "PURCHASE_HISTORY_UPDATED"
  },
  "message": "Update purchase history success.",
  "data": {
    "_id": "66f000000000000000000401",
    "purchaseID": "ORD20269268300418273",
    "communityID": "66f000000000000000000010",
    "userID": "<userObjectId>",
    "status": "Completed",
    "purchaseStatusID": "66f000000000000000000405",
    "price": 500,
    "quantity": 1,
    "voucherCode": "TC25-8R5N-3C1Y",
    "voucherExpiryDate": "2026-12-31T00:00:00.000Z",
    "voucher": {
      "_id": "66f000000000000000000502",
      "code": "TC25-8R5N-3C1Y",
      "status": "redeemed",
      "expiryDate": "2026-12-31T00:00:00.000Z"
    },
    "product": {
      "_id": "66f000000000000000000101",
      "name": "$25 Trading Credit",
      "description": "<p>Redeem 500 coins for a $25 trading credit on your live account.</p>",
      "image": "https://cdn.example.com/store/trading-credit-25.png",
      "price": 500,
      "type": "voucher",
      "redemptionInstructions": "Your $25 credit is added to your live trading account within 2 business days."
    },
    "userInfo": {
      "username": "sample_trader",
      "name": "Sample Trader",
      "email": "trader@example.com"
    },
    "customOptions": [],
    "purchasedDate": "2026-09-26T08:30:00.000Z",
    "latestStatusHistory": {
      "oldStatusName": "New Purchase",
      "newStatusName": "Completed",
      "remark": "Updated by API",
      "createdAt": "2026-09-26T09:15:00.000Z"
    },
    "createdAt": "2026-09-26T08:30:00.000Z",
    "updatedAt": "2026-09-27T10:15:00.000Z"
  }
}

Errors#

Every error carries its code in meta.code, with the reason in detail, except a 400 for a body of the wrong shape, which has no code and puts the reason in detail.body.

Fix the request05

400Fix the request
The body's shape is wrong, and there is no meta.code. detail.body says which: an empty body, a field this endpoint doesn't take, both kinds of change in one request, or a form answer with both or neither of name and _id. Nothing was changed.
400VALIDATION_FAILEDFix the request
A value broke a rule, and nothing was changed. detail says which: for example a voucher code sent without its expiry date, a date not in DD/MM/YYYY, a blank value, an unknown form field name, or No purchase history details changed when every value already matches.
401AUTH_API_KEY_REQUIREDFix the request
No key was sent. Send Authorization: Bearer <API_KEY>.
401AUTH_API_KEY_INVALIDFix the request
The key is unknown, expired or malformed. Use a current Community API key.
403AUTH_PERMISSION_REQUIREDFix the request
The key lacks purchase-history. Add the permission in Settings > Integration > API Keys.

Fix the data02

404STORE_RESOURCE_NOT_FOUNDFix the data
Nothing changed. detail says which: Purchase history not found (check the ORD... order ID from the order lists), or Product not found for purchaseHistory (the product was deleted, so instructions can't be set; voucher and customer changes still work).
409STORE_RESOURCE_CONFLICTFix the data
Another voucher on the same product already has this code, and nothing was changed. Use a different code.

Retry with backoff03

502STORE_DEPENDENCY_UNAVAILABLERetry with backoff
The outcome is unknown. Read the order, then send the update again if it didn't apply.
500INTERNAL_ERRORRetry with backoff
The outcome is unknown. Read the order, then send the update again if it didn't apply.
401AUTH_API_KEY_VALIDATION_FAILEDRetry with backoff
The key could not be checked just now, and nothing was changed. Retry with backoff.
{
  "meta": {
    "status": "error",
    "statusCode": 400,
    "code": "VALIDATION_FAILED"
  },
  "message": "Validation failed",
  "detail": {
    "voucherExpiryDate": "voucherExpiryDate must be a valid date in DD/MM/YYYY format"
  },
  "solution": "Please check the request and try again"
}

Next step#

Get redemption transaction detailGET/v2/redemption-transactions/{redemptionID}Read the order back to confirm what the trader sees.