Accepts a CSV file of customers affected by one or more product recalls and asynchronously
triggers the configured recall Journey for each row. Use this endpoint instead of
POST /erc/ecommerce/recall/contacts when the list is large or comes from a spreadsheet.
A row is one customer and one product. The same customer may appear on several rows with
different products, which are treated as separate recalls; the same customer and product
pair may appear only once.
The file is validated synchronously and as a whole: if any row is invalid, or any
customer_id is unknown under the given brand, nothing is sent and the response lists the
problems found. A recall is never delivered to only part of a file. Only a fully valid file
is accepted and queued for asynchronous Journey triggering.
The 202 response only means that the file was valid and has been queued. Delivery to the
Journey is asynchronous and best effort: there is no status endpoint or callback, and a batch
that still fails after retries is not reported back to the caller. The returned upload_id
identifies the upload for support and log correlation only; no endpoint accepts it. Uploads
are not de-duplicated, so submitting the same file twice sends every message twice.
CSV file format
The file is a comma-separated, UTF-8 text file (a leading byte order mark is accepted). Fields
that contain a comma, quote or line break must be wrapped in double quotes, with a quote inside
a field doubled ("Smith, Alice"), as in RFC 4180. Leading and trailing spaces around a value
are ignored and empty lines are skipped.
The first row is a header naming the columns. Column names are matched by name, not position,
and are not case-sensitive. The columns can be in any order, and any additional column is
ignored. All eight columns below are required and every cell in them must be non-empty.
| Column | Max length | Description | Example |
|---|---|---|---|
customer_id | The customer's identifier under the given brand. Rows whose customer is unknown are reported as CUSTOMER_NOT_FOUND. | 7710396907579 | |
name | 100 | The customer's name, used as written in the message. | Alice Smith |
phone | A real phone number with a country code. Spaces, dashes and brackets are accepted (+1 (201) 555-0123); it is converted to E.164 before it is sent. A number without a country code is rejected with UNUSABLE_CONTACT. | +12015550123 | |
email | The customer's email address, in the form [email protected] with no spaces. Addresses that cannot reach anyone are rejected with UNUSABLE_CONTACT. | [email protected] | |
product_name | 255 | The name of the recalled product, as the customer should read it. Not checked against the product catalogue. | Widget |
reason_for_recall | 500 | A short, customer-facing description of why the product is recalled. | Battery overheating risk |
skus | One or more SKUs of the recalled product, separated by |. Values are trimmed and repeated values are removed; the message shows them joined with , . | SKU-A|SKU-B | |
order_numbers | One or more customer-facing order numbers the recall applies to, separated by |, normalised like skus. | 1001|1007 |
Spreadsheet tools often drop the leading + of a phone number, or turn the column into a
number, when saving as CSV; every row is then rejected as UNUSABLE_CONTACT. Format the phone
column as text so that the + is kept.
Example file:
customer_id,name,phone,email,product_name,reason_for_recall,skus,order_numbers
C1,Alice Smith,+12015550123,[email protected],Widget,Battery overheating risk,SKU-A|SKU-B,1001|1007
C2,Bob Jones,+1 (201) 555-0124,[email protected],Widget,Battery overheating risk,SKU-A,1002
C1,Alice Smith,+12015550123,[email protected],Gadget,Loose strap,SKU-C,1003
Each row is one customer and one product, and becomes one message. In the example, Alice
receives two messages because she appears with two different products, while Bob receives one.
A customer_id and product_name pair may appear only once in a file; a repeat is rejected
with DUPLICATE_CUSTOMER_PRODUCT.
Limits
The file may be at most 5 MiB (5,242,880 bytes) and contain at most 20,000 data rows (the header row is not
counted). Above the row limit the upload is rejected with TOO_MANY_ROWS; above the size limit
it is rejected with 413.
Validation errors
Every problem found is collected, and up to the first 100 are returned. Each entry names the
row (the header is row 1) and the column, followed by one of these reasons:
| Reason | Meaning |
|---|---|
EMPTY_FILE | The file is empty. |
NO_DATA_ROWS | The file has a header but no data rows. |
MISSING_HEADER | A required column is missing from the header row. |
MALFORMED_ROW | The file is not valid UTF-8 CSV (for example an unclosed quote). Reading stops at this point. |
TOO_MANY_ROWS | The file has more than 20,000 data rows. Reading stops at this point. |
BLANK_REQUIRED_VALUE | A required cell is empty. |
VALUE_TOO_LONG | name, product_name or reason_for_recall exceeds its maximum length. |
UNUSABLE_CONTACT | phone is not a real number with a country code, or email is not a usable address. The rejected value is not repeated in the response. |
DUPLICATE_CUSTOMER_PRODUCT | The same customer_id and product_name appear on more than one row. |
CUSTOMER_NOT_FOUND | The customer_id does not exist under the given brand. |
When the file cannot be read to the end (EMPTY_FILE, NO_DATA_ROWS, MISSING_HEADER,
MALFORMED_ROW, TOO_MANY_ROWS), customers are not looked up, so only that reason is reported.
Message variables
For each accepted row the Journey is triggered with these variables: customer_id,
customer_name, phone (in E.164), email, brand, brand_name, reason_for_recall,
product_name, skus and order_numbers. skus and order_numbers hold the normalised
values from the file. Unlike POST /erc/ecommerce/recall/contacts, no product_id is sent, as
nothing in the file is checked against the customer's orders.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||