Create async orders
This Tango API endpoint enables you to create asynchronous orders for distributing rewards under a specific account. It's designed for multiple line items, where you need to send rewards to recipients with various delivery methods. The asynchronous orders are also efficient for large-scale reward campaigns.
Endpoint
Use the asynchronous orders endpoint to create a batch of rewards:
| Endpoint | Purpose |
|---|---|
POST {URI}/asyncOrders | Create a batch of rewards that will be processed asynchronously. |
Use case
Acme Corp runs quarterly employee recognition and customer loyalty programs. Each cycle, they distribute hundreds of digital and physical rewards to recipients across different regions and departments. They use async order placement with this endpoint to submit rewards with multiple line items in a single request. They can track delivery status via the GET /asyncOrders endpoints without exposing reward credentials while customizing delivery methods per recipient (email, SMS, physical mail). They can receive webhook notifications when the order has completed.
Parameters
The following body parameters are used with this endpoint:
Body params | Data type | Requirement | Description |
|---|---|---|---|
externalRefID | string | required | An idempotent field for your order cross-reference and to prevent accidental order duplication. This value is returned in the order response, order details, and order history. The string has a maximum of 100 alphanumeric characters. |
customerIdentifier | string | required | Specify the customer associated with the order. Must be the customer that the |
accountIdentifier | string | required | Specify the account from which this order will be deducted. The string must be 5-100 characters long. |
sender | object | optional | Use to set the sender’s name and email address if they differ from the default platform setting. The sender overrides the default platform sender settings. |
sender.firstName | string | optional | Always optional, string, 100 characters max |
sender.lastName | string | optional | Always optional, string, 100 characters max |
sender.email | string | optional | Always optional, string |
campaign | string | optional | A campaign that may be used to group orders under a particular campaign. The maximum length is 1024 characters, including special characters such as @, #, %, etc. |
purchaseOrderNumber | string | optional | Associates a purchase order number with the order. The string may have up to 100 characters. |
notes | string | optional | Additional order-level notes. The string may have up to 150 characters. |
lineItems | array of objects | required | Contains the order details, including recipient, reward, and delivery method. At least one line item is required. |
lineItems[].externalRefLineItemID | string | required | An idempotent field that can be used for client-side order line-item cross-reference and to map failed and successful line items on the client side. The string may have up to 150 characters. |
lineItems[].recipient | object | required | Required if |
lineItems[].recipient.firstName | string | required if | Required when |
lineItems[].recipient.lastName | string | required if | Required if |
lineItems[].recipient.email | string | required if | Required if |
lineItems[].recipient.mobileNumber | string | required if | Required when
|
lineItems[].recipient.address | object | required if | Required when
|
lineItems[].recipient.address.companyName | string | optional | Typically used when shipping to a corporate address. |
lineItems[].recipient.address.streetLine1 | string | required if | Required if |
lineItems[].recipient.address.streetLine2 | string | optional if | Optional if |
lineItems[].recipient.address.city | string | required if | Required if |
lineItems[].recipient.address.stateOrProvince | string | required if | Required if |
lineItems[].recipient.address.postalCode | string | required if | Required if |
lineItems[].recipient.address.country | string | required if | Required if |
lineItems[].utid | string | required | The unique identifier for the reward you are sending, as provided in the Get Catalog call. |
lineItems[].amount | number | required | Specify the face value of the reward. Amount is always needed, including for fixed value items. |
lineItems[].quantity | integer | optional | Number of rewards to create for the line item. If missing, it defaults to 1. The quantity must be 1 or greater. If greater than 1, |
lineItems[].deliveryMethod | string | required | Specify the |
lineItems[].deliveryDate | date | optional | Specify the date to deliver the reward to the recipient. It must be at least 7 days in the future. If not specified, the reward will be immediately send. |
lineItems[].etid | string | optional | Used with |
lineItems[].ptid | string | required if | Printed Reward Link Template identifier is used only for Printed Reward Links. It's provided in the Tango Portal on the Printed Template page. |
lineItems[].expirationDate | datetime | optional | The expiration date for Promo Links. Sets the exact calendar date the Promo Link will expire, following the ISO 8601 format. See Promo Link acceptance criteria. |
lineItems[].emailSubject | string | optional | If not specified, a default email subject will be used for the specified reward. |
lineItems[].message | string | optional | Gift message. The string may have up to 1024 characters. |
lineItems[].lineItemNote | string | optional | Optional line item notes (up to 150 characters) |
lineItems[].shipping | object | optional | The shipping is required for delivery when deliveryMethod=BULKSHIPMENT. It is used to specify where the bulk shipment should be sent. |
lineItems[].shipping.companyName | string | optional | The name of the company where the shipment is being delivered. |
lineItems[].shipping.contactName | string | optional | 50 characters max. The name of the person receiving the shipment. |
lineItems[].shipping.contactEmail | string | optional | The email address of the person receiving the shipment. |
lineItems[].shipping.contactPhoneNumber | string | optional | The phone number of the person receiving the shipment |
lineItems[].shipping.Address | object | required | The shipping address for delivery. |
lineItems[].shipping.address.streetLine1 | string | required | 35 characters max, not blank, Digits 0-9, alpha (a-z, A-Z), space, period, comma, hyphen, forward slash (/), ampersand, percent, pound (#), at (@), and apostrophe. |
lineItems[].shipping.address.streetLine2 | string | optional | 35 characters max, Not blank, Digits 0-9, alpha (a-z, A-Z), space, period, comma, hyphen, forward slash (/), ampersand, percent, pound (#), at (@), and apostrophe. |
lineItems[].shipping.address.city | string | required | 35 characters max, not blank, Digits 0-9, alpha (a-z, A-Z), space, period, hyphen, ampersand, and apostrophe. |
lineItems[].shipping.address.stateOrProvince | string | required | 36 characters max, Address region must be a valid 2-character uppercase abbreviation for a U.S. state, territory, or military base; a Canadian province; or contain an international region less than 36 characters. |
lineItems[].shipping.address.postalCode | string | required | Allows 5 characters, not blank, Digits 0-9 and alpha (a-z, A-Z). For US addresses, this must include only the five-digit US ZIP Code. |
lineItems[].shipping.address.country | string | required | 2 characters, Enter the ISO 3166-1 alpha-2 country code. |
lineItems[].shippingMethod | string, enum | optional | Enumeration for the selected shipping method. Required for |
*See the description for more information.
External reference ID
To prevent duplicate order submissions, the POST {URI}/asyncOrders endpoint now validates incoming externalRefID values against existing orders.
- If the
externalRefIDwas previously used withPOST {URI}/orders, the request fails with a descriptive error. - If the
externalRefIDwas previously used withPOST {URI}/asyncOrders, the endpoint returns the status of the existing order instead of creating a new one.
Behavior change:This endpoint now enforces delivery‑specific validation for
quantity,recipient, andshippingfields. Existing integrations that usedquantity > 1with unsupported delivery methods will receive validation errors and must be updated to useBULKDIGITALorBULKSHIPMENTfor bulk quantities.
Bulk quantity, shipping, and recipient rules
The following table summarizes how bulk quantity, shipping, and recipient requirements vary by delivery method:
| Delivery Method | Quantity > 1 allowed | Shipping object | Recipient object |
|---|---|---|---|
| BULKDIGITAL | Yes | Not allowed | Not allowed |
| BULKSHIPMENT | Yes | Required | Not allowed |
| No | Not allowed | Required | |
| PHONE | No | Not allowed | Required |
| EMBEDDED | No | Not allowed | Required |
| ADDRESS | No | Not allowed | Required |
| NONE | No | Not allowed | Required |
Notes:
- For
BULKDIGITALandBULKSHIPMENT, do not include arecipientobject. ForBULKSHIPMENT, provide delivery information inshippinginstead.- Quantity defaults to 1 when missing. It must be 1 or greater for bulk digital and bulk shipment. If
quantityis greater than1,deliveryMethodmust beBULKSHIPMENTorBULKDIGITAL.- Any delivery method not listed as supporting bulk quantity will fail if quantity is greater than 1.
- Including a shipping object when it is not allowed will fail validation.
- Missing or extra recipient objects will fail validation based on the delivery method.
- Invalid requests return 422 Unprocessable Entity with a descriptive error message.
Examples
The following example illustrates the payload for using this endpoint and its parameters.
{
"externalRefID": "string",
"status": "string",
"totalLineItems": 0,
"createdAt": "2025-10-23T21:52:43.041Z",
"failedLineItems": [
{
"lineItemId": "string",
"externalRefLineItemID": "string",
"utid": "string",
"errors": [
{
"field": "string",
"errorCodeValue": 0,
"errorCodeName": "string",
"message": "string"
}
]
}
],
"duplicateLineItemRefIds": {
"additionalProp": 0
}
}Here is the successful response example:
{
"externalRefID": "ORDER-2025-001",
"order": {
"externalRefID": "ORDER-2025-001",
"status": "pending",
"totalLineItems": "2",
"created_at": "2025-05-07T10:00:00Z"
}
}Response codes
The possible response codes for this endpoint are as follows. For details, see i18nkey codes and their error messages:
| Response code | Meaning |
|---|---|
| 200 | The request was successful. |
| 201 | A new resource has been successfully created in response to the request. |
| 400 | The server could not understand the request due to invalid syntax. |
| 401 | Authentication is required and has either not been provided or failed. |
| 402 | There are insufficient funds. |
| 403 | The server understood the request but refused to authorize it. |
| 422 | The server understands the request but cannot process it due to semantic errors. |
| 429 | Exceeded the allowable TPS rate limit. It indicates that the user has sent too many requests within a given time frame, and the server is rate-limiting further requests. |
| 500 | An error occurred on the server, but the server cannot provide a more specific description of the exact problem. |
| 503 | The server is currently unable to handle the request due to temporary overload or maintenance. |
Updated 4 days ago
