LuxSci functional guide
Overview
The following guide provides information about the capabilities of LuxSci within Redpoint Interaction (RPI), how sending emails/synchronizing state data works, and links to other resources.
Key capabilities
The LuxSci connector provides the following key capabilities:
Channel configuration
The ability to send emails via an Interaction using an Offer Activity and Queue Listener
Receiving state/disposition data via the Channel Synchronization Task
Using state/disposition data as inputs to additional workflows and downstream activities
Unique features
The LuxSci connector supports the following features:
Ability to send secure messages
Ideal platform to use for Queue Listeners as they support timely delivery of emails
Support for BCC within the channel configuration
Various channel configuration options to optimize performance for outbound and inbound processing
The ability to inspect Mail Merge files for auditing purposes
The ability to support custom headers at the channel level
The ability to import email reports using bulk method
Process flow
The following flow chart shows how the LuxSci channel works within both outbound fulfillment and inbound state synchronization.
Outbound processing
Inbound processing
Outbound fulfillment
The LuxSci connector performs the following steps when it is used as part of an outbound Offer Activity.
Step 1
Initiate a connectivity test to validate the credentials configured in the channel are valid.
Method
POST
Endpoint
https://rest.luxsci.com/perl/api/v2/auth
Request Body
{
"user": "<user_name>",
"pass": "<luxsci_password>",
"token": "<api_token>",
"secret": null,
"debug": null,
"date": "1689322869",
"signature": "<signature>"
}
Response Body
{
"auth": "<auth_value>",
"success": 1
}
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/profile
Cookie
signature=<cookie_signature>
Response Body
{
"auth": "107302356-1689322872-64777db2cbccaed15be87757dc93cf7139b5ad020dfba8ab2b943c1b0f8f25a8",
"success": 1,
"data": {
"contact": "<user_name>",
"city": null,
"custom1": null,
"services": [
"imap",
"pop",
"smtp",
"spam",
"ftp",
"website"
],
"zip": null,
"custom2": null,
"created": "2021-02-18 18:03:09",
"custom3": null,
"phone2": null,
"uid": "163972",
"secret_a": null,
"company": null,
"street2": null,
"account": 19172,
"phone1": "+1 781 725 0250 x1330",
"last_access_date": "2023-07-14 07:07:26",
"email1": "<account_email>",
"flags": [],
"fax": null,
"secret_q": null,
"street1": null,
"country": null,
"disk_quota": -1,
"email2": null,
"state": null,
"disk_used": "0.002"
}
}
Step 2
If the channel is configured to auto-suppress unsubscribes, RPI will query the suppression email table to identify and suppress any matching email addresses before generating the mail merge files.
Step 3
Create LuxSci template.
Method
PUT
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/templates
Request Body
{
"template_id": 0,
"code_word": null,
"title": "RPI_<QL if running queue listener><offertemplate_instance_id><channelexecution_id><3_characters_initial_channel_id><3_characters_client_id>",
"subject": "<email_subject>",
"body_html": "<html_content>",
"body_text": "<text_content>",
"format": "<both/html/text>",
"sl_opt_in": true,
"sl_opt_out": false,
"sl_no_tls": "<true/false if secure message>"
}
Step 4
Use the Razor templating engine to render personalization and dynamic content to create the mail merge files.
Step 5
Files are batched based on the unique sets of content across HTML, Text, and Subject Line assets.
AND
Each batch file includes up to 1000 recipients, per the max allowed by LuxSci.
Step 6
RPI will loop through each of the files and initiate the send to LuxSci.
In cases where one or more batches failed to send, the workflow can be replayed again to pick up failed batches and retry to send the emails.
Email events are tracked by using header chid
which can be configured in the LuxSci portal. chid
value is formatted as <ChannelExecutionID>_<OfferTemplateInstanceID>_<ChannelID>_<RPContactID>
.
Method
POST
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/email/send
Request Body
{
"message": null,
"messages": [
{
"from_address": "dev@luxsci.net",
"subject": null,
"no_tls_only": 1,
"body": null,
"body_text": null,
"to": [
"<recipient_email>"
],
"from_name": "Developer",
"receipt": 0,
"body_type": null,
"bcc": null,
"headers": [
["chid", "2790_2790_21f174d0fe8442a9acf096bbd437276c_1380076"],
["offername", "June Sales"],
["rpid", "M"]
],
"reply_address": "dev@luxsci.net",
"template": "330814",
"template_data": {
"EmailAddress": "<recipient_email>",
"RPContactID": 1380076,
"NameStyle": true,
"Gender": "F",
"SR_Female": "Y",
"CustomerKey": 11507,
"FirstName": "Isabella",
"Customer_Key": 11507,
"SR_Male_580": "N",
"c64b8bcd80b646048ba7168e6631b74b0.1_dyc_html": "<smartasset_content>",
"89b2b377169c460bae24f621bc8fe2330.3_dyc_html": "<smartasset_content>"
},
"template_data_raw": 1,
"unsubscribe": 1
}
],
"sandbox": 0
}
Response Body
{
"data": [
"37IFXe008i13463",
"37IFXe009i13463",
"37IFXe00Ai13463"
],
"success": 1,
"auth": "107842778-1689694420-38859d84ffabf5cc11ed2522a9c0da8a5c3cd7e717c9d3a9143f4f3494ccc7b5"
}
Step 7
RPI will save the tracking id to table.
Tracking ID format:
<ChannelExecutionID>_<OfferTemplateInstanceID>_<ChannelID>
Table:
RPI_LuxSciTracking
Step 8
Delete LuxSci template.
If running queue listener, templates are persisted and deleted only once workflow is rolled back or Template retention period has elapsed as part of the housekeeping task.
Method
DELETE
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/template/<template_id>
Response Body
{
"auth": "107842778-1689694486-fbb0e71cfb3ed053db510446037af5ed63b8b7808c466b13f7674aba1e260886",
"success": 1
}
Step 9
Once the sends are complete, the Interaction Log is updated with the total number of batch files that processed successfully/failed.
State data synchronization
The following steps make up the inbound process.
Step 1
If Import via file is checked, download email report for each event as follows:
Sent
Delivered
Opened
Clicks
Feedbackloop
The following make up the Sent Request:
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/report/email/smtp/sent?tracked_headers=true&first_row=0&matches=1&after_date=2023-07-18+08%3A38%3A02&header1=chid&header1_operator=like&header1_value=_<channel_id>
Response Body
{
"success": 1,
"data": {
"matches_total": 6,
"rows": [
[
"<luxsci_username>",
"163972",
"2023-07-18 15:33:40",
"180.190.229.9",
1,
1,
1455,
"Test Email form diff table",
"<sender_email>",
"<recipient_email>",
0,
1,
1,
0,
null,
"37IFXe00Ai13463",
"330814",
"chid",
"2790_2790_<channel_id>_1380076",
"rpid",
"M",
"offername",
"June Sales"
]
],
"header": [
"user",
"user_id",
"date_sent",
"from_ip",
"used_tls",
"n_recipients",
"size_bytes",
"subject",
"from",
"to",
"spam",
"high_volume",
"secureline",
"opt_out",
"notes",
"sendmail_id",
"template_id",
"header1",
"header1_value",
"header2",
"header2_value",
"header3",
"header3_value"
],
"matches_returned": 1,
"first": 3
},
"auth": "107848470-1689699603-7874819666f314612ef0db043a3c4d165a3c2286f0edfc6c4a818a2bd44d1551"
}
The following make up the Delivered Request:
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/report/email/smtp/delivery?tracked_headers=true&first_row=0&matches=1&after_date=2023-07-18+08%3A38%3A28&header1=chid&header1_operator=like&header1_value=_<channel_id>&sent_date=0
Response Body
{
"auth": "107848470-1689699604-bf0c207657faefa9a0b45559fbc62ca4965a1104282e28779faf38b75ff447b7",
"success": 1,
"data": {
"matches_total": 8,
"rows": [
[
"2023-07-17 08:16:16",
"<luxsci_username>",
"163972",
"180.190.229.9",
1,
1734,
"Link Metrics Testing",
"<sender_email>",
"<recipient_email>",
"Delivered",
"gmail-smtp-in.l.google.com said 'Sent (OK 1689581778 l23-20020a63ba57000000b005578c6a767esi11084815pgu.885 - gsmtp'",
"2023-07-18 03:44:32",
4,
1,
"TLSv1.3: cipher=TLS_AES_256_GCM_SHA384, bits=256/256",
"37H8GG002i71587",
"330654",
null,
1,
3,
0,
"chid",
"2787_2787_<channel_id>_1380067",
"rpid",
"M",
"offername",
"June Sales"
]
],
"header": [
"date_sent",
"user",
"user_id",
"from_ip",
"n_recipients",
"size_bytes",
"subject",
"from",
"to",
"status",
"details",
"last_updated",
"secureline",
"tls_delivery",
"tls_details",
"sendmail_id",
"template_id",
"notes",
"Opens",
"Clicks",
"Unsubscribed",
"header1",
"header1_value",
"header2",
"header2_value",
"header3",
"header3_value"
],
"matches_returned": 1,
"first": 0
}
}
The following make up the Opened Request:
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/report/email/smtp/opens?tracked_headers=true&first_row=1&matches=1&after_date=2023-07-18+05%3A17%3A06&header1=chid&header1_operator=like&header1_value=_<channel_id>&open_date=1
Response Body
{
"data": {
"matches_total": 2,
"rows": [
[
"2023-07-17 08:16:16",
"2023-07-17 11:58:46",
"69.147.89.136",
"YahooMailProxy; https://help.yahoo.com/kb/yahoo-mail-proxy-SLN28749.html",
"admin@redpointglobal3.trial6.luxsci.net",
"163972",
"Link Metrics Testing",
"dev@luxsci.net",
"<recipient_email>",
"Delivered",
"37H8GG002i71587",
"330654",
"chid",
"2787_2787_21f174d0fe8442a9acf096bbd437276c_1380067",
"rpid",
"M",
"offername",
"June Sales"
]
],
"header": [
"date_sent",
"open_date",
"opener_ip",
"user_agent",
"user",
"user_id",
"subject",
"from",
"to",
"status",
"sendmail_id",
"template_id",
"header1",
"header1_value",
"header2",
"header2_value",
"header3",
"header3_value"
],
"first": 0,
"matches_returned": 1
},
"auth": "107848470-1689699628-7847ea8c44f21f92ef16e06f8c8e96f31c6dc9cd4a7c3988339b571772ac25d8",
"success": 1
}
The following make up the Clicks Request:
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/report/email/smtp/clicks?tracked_headers=true&first_row=0&matches=10000&after_date=2023-07-17+12%3A17%3A43&header1=chid&header1_operator=like&header1_value=_<channel_id>&click_date=1
Response Body
{
"data": {
"rows": [
[
"2023-07-17 08:16:16",
"2023-07-17 12:17:44",
"http://www.example.com",
"180.190.229.9",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"<luxsci_username>",
"163972",
"Link Metrics Testing",
"<sender_email>",
"<recipient_email>",
"Delivered",
"chid",
"2787_2787_<channel_id>_1380067",
"rpid",
"M",
"offername",
"June Sales",
"37H8GG002i71587",
"330654"
]
],
"matches_returned": 3,
"header": [
"date_sent",
"click_date",
"url",
"clicker_ip",
"user_agent",
"user",
"user_id",
"subject",
"from",
"to",
"status",
"header1",
"header1_value",
"header2",
"header2_value",
"header3",
"header3_value",
"sendmail_id",
"template_id"
],
"first": 0,
"matches_total": 3
},
"auth": "107848470-1689699627-55b51c651b9d276e54fd01f6ab39d1749b3a9259be09eac5c3b805c1ee9048e1",
"success": 1
}
The following make up the Feedback Loop Request:
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/report/email/fbl?tracked_headers=true&first_row=0&matches=1&after_date=2023-03-31+15%3A26%3A19&header1=chid&header1_operator=like&header1_value=_<channel_id>
Response Body
TBU
Step 2
RPI will create a request export job to LuxSci. After LuxSci generates the report, it uploads them to the specified Report destination.
LuxSci currently supports SFTP as the Report destination.
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/report/email/<smtp|fbl>/<sent|delivery|clicks|open>?tracked_headers=true&first_row=3&matches=3&after_date=2023-07-17+08%3A16%3A15&header1=chid&header1_operator=like&header1_value=_<channel_id>&destination=sftp&destination_directory=<sftp_folder>&destination_hostname=<sftp_hostname>&destination_password=<sftp_password>&destination_username=<sftp_username>
Response Body
{
"auth": "107828390-1689671756-0e0c016f84000890eea2df6bd368cac3949d14b51193bd93f2d00a8f1a31adac",
"success": 1,
"data": {
"current_jobs": 1,
"filename": "1689671756-1485-20872.csv",
"max_jobs": 2,
"job_id": "310383"
}
}
Step 3
RPI will create a request which monitors the export job. It checks whether the jobs status is completed or failed.
If the “max jobs” is already at the limit, RPI will wait 60 seconds to check again if there are available job slots to make the request. Job request will fail if the number of retries has reached the limit as imposed by Async report retry in the channel config.
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/jobs
Response Body
{
"success": 1,
"data": [
{
"created": "2023-07-12 00:10:15",
"status_detail": null,
"updated": "2023-07-12 00:10:17",
"completed": "2023-07-12 00:10:17",
"current_jobs": 0,
"filename": "1689120615-1484-3611676.csv",
"uid": "163972",
"completed_rows": 2,
"job_id": "310022",
"status": "complete",
"max_jobs": 2,
"expected_rows": 2,
"hostname": "rs6020.luxsci.com"
}
]
}
Step 4
After the export job has completed, RPI will download the LuxSci generated email report from the Report destination to the configure State results folder path.
Step 5
Once the report is downloaded, RPI will delete the file in the Report destination.
Step 6
Run a Redpoint Data Management (RPDM) job located in this path /RedPoint/Interaction/Import/Channels/Email/Load.LuxSci.EmailActivities
in RPDM to import the email report to the configured Import table name.
Step 7
If the RPDM job has completed, delete the used files in the State results folder path.
During this process, any report files older than 7 seven days are also deleted.
Step 8
Email events are inserted to Offer History State table.
If OverrideOHStateTimestampUsingServerTimezone
config is checked, event timestamp will display as local server time.
Step 9
HardFail
, Failed
, and Spam
fulfillment state are loaded into suppression table.
Step 10
Email suppression list from LuxSci is downloaded and inserted into the suppression table.
Method
GET
Endpoint
https://rest.luxsci.com/perl/api/v2/user/<luxsci_username>/suppression
Response Body
{
"data": [
[
"<recipient_email>",
0,
19172,
28594,
"163972",
"2022-10-10 08:59:28",
"Unsubscribe link used from 180.190.31.26"
]
],
"success": 1,
"auth": "107828390-1689671825-a9ba790e94f3605e73f8429948a91d255e8b41729edc11b2fea2427d6050e874"
}
Step 11
Update the state and metrics count.
LuxSci configuration
The following section provides the pre-requisite steps for configuring LuxSci to work with RPI.
To create tracking header:
In a web browser, navigate and log in to Luxsci.
Navigate to Administration Home>Admin Settings>Outbound Email>Settings.
Under Account Settings - Email panel, scroll down to SMTP Header Tracking and add
chid
as the Header 1. Thechid
header will contain specific information when emails are sent to track email events.

Select Save Changes.
Performance testing
Test environment
Performance testing was last performed in August 2023 using the environment below:
Redpoint Interaction
2 VMs with 8 cores and 32GB of memory
2 nodes
Azure SQLDB elastic pool instance for the marketing and ops database
Redpoint Data Management
1 VM with 4 cores and 16GB or memory
Snowflake
Snowflake Client (v7.28)
Snowflake ODBC driver (3.00.02.00)
LuxSci
Server Name: rs7392.luxsci.com (API Server)
Server Type: Oracle Cloud
Public IP: 129.146.161.64
Private/Local IP: 10.10.0.102
CPU: 4 cores
RAM: 16 GB
Operating System: Linux v8.7 64bit
LuxSci Software: v23.1.3
Apache: v2.4.54PHP: v8.0.26
MariaDB: v10.4.27
ProFTPd: v1.3.7f
ClamAV: v1.0.0
OpenSSL: v1.1.1s
Server Name: rs7393.luxsci.com (SMTP Server)
Server Type: Oracle Cloud
Public IP: 162.142.76.112
Private/Local IP: 10.10.1.113
CPU: 2 cores
RAM: 16 GB
Operating System: Linux v8.7 64bit
LuxSci Software: v23.1.3
MariaDB: v10.4.27
ClamAV: v1.0.0
OpenSSL: v1.1.1s
Volume test results
The Contact Personalization reflects the time to create the batch within Redpoint Interaction on an environment scaled as indicated above. The Luxsci Batch Upload time reflects the time to process the batch within the vendor (outside of Redpoint Global) and will vary based upon your subscription with Luxsci. Testing was done on their shared testing instance, which should be slower than your private testing instance.
Batch sends
Batch Sends | Contact Personalization (RPI Processing) | Luxsci Batch Upload (Luxsci Processing) | Total Workflow Execution |
---|---|---|---|
1M | 34m35s | 1h43m44s | 2h20m53s |
2M | 1h4m12s | 3h22m11s | 4h29m17s |
3.5M | 2h1m45s | 6h15m48s | 8h21m5s |
5M | 2h56m19s | 9h39m30s | 12h39m57s |
Concurrent sends
Concurrent workflow running (batch size) | Earliest start time | Earliest end time | Total offer execution |
---|---|---|---|
20 (50K) | 23:25:09 | 01:11:27 | 1h46m18s |
20 (150K) | 13:56:05 | 21:23:12 | 7h27m7s |
Inbound processing
Number of Events (data processed) | Channel Synch Execution |
---|---|
50K | 1M10s |
500K | 20M17s |
1M | 23M41S |
Limitations
Limitation # | Limitation Detail |
---|---|
1 | The API does not support the option to create “View as Web Page” links that mirror the email content. |
2 | The ability to schedule a delivery is not supported by their API. |
3 | The use of social elements including Facebook Like Image and Facebook Like Share buttons are not supported. |
4 | The “Forward-to-Friend” option is not supported. |
5 | The use of content sharing for Facebook and Twitter is not supported. |
Logging
Below is an example of the Interaction log for an offer using the LuxSci channel:
Log | Log entry description |
---|---|
2023/07/18 23:34:46 Fulfillment Action complete | Batch Total: 1 Batch Success: 1 Batch Failed: 0 = the total number of batch files that was successful vs failed Processed XX of XX batch files = the number of batch files that was processed to send emails Merge contact data completed. XX = the number of recipients to send emails Deleting template 330814 = Initiates delete of template Message tracking ID save to database: 2790_2790_21f174d0fe8442a9acf096bbd437276c = the tracking ID that was successfully saved in the tracking table <FileOutputDirectory>\WFAI2748\Offer 2 2 2\New LuxSci Channel 2 1\RPI_2790_2790_21f_238\process = The location where batch files are located Other messages: Invalid seed email(s): XX = the number of seeds with invalid email address Merge seed data completed: XX = the number of seeds to send emails |
FAQ
What if “Invalid seed email(s)” are reported even if the email addresses are valid?
Make sure that the attribute used as Recipient email in channel admin or Recipient Email Attribute Override in email offer is present as one of the seed attributes.
What if metrics are missing when executing Queue Listener using Snowflake DB?
Using uppercase or mixed case as email address when executing Queue Listener will result to missing metrics when using Snowflake DB because it compares string as case sensitive. Make sure to use lowercase email address when executing QL in Snowflake DB.
Which error codes are retry-able?
Timeout
ConnectFailure
SecureChannelFailure
ProtocolError
ReceiveFailure
NameResolutionFailure
SendFailure
ServerProtocolViolation
KeepAliveFailure
GatewayTimeout
BadGateway
ExpectationFailed
RequestTimeout
NotFound
ServiceUnavailable
TooManyRequest
What is the current re-try strategy employed if API requests to LuxSci fail?
If API request fails, LuxSci connector employed Exponential Backoff re-try strategy.
Normally, the interval of each attempt will exponentially be increasing the waiting time e.g., 1s, 2s, 4s... etc. until the max retry count has been reached. The number of attempts is configurable via API Call max. retries setting in LuxSci channel with default value of 10
.
Do we enforce any specific encoding on any of our asset types?
No.
What specific encoding do we use when communicating with LuxSci?
UTF-8