-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sub endpoint #1
Open
this-sam
wants to merge
4
commits into
master
Choose a base branch
from
sub-endpoint
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Sub endpoint #1
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,142 @@ | ||
# Traverse Email Retargeting Publisher Documentation | ||
#### Traverse Email Retargeting | ||
# Publisher Documentation v1.1 | ||
|
||
|
||
|
||
## Contents | ||
|
||
1. [Overview](#overview) | ||
2. [Getting started](#getting-started) | ||
3. [Best practices](#best-practices) | ||
4. [Security](#security) | ||
5. [Syncing your subscribers](#syncing-your-subscribers) | ||
6. [Receiving campaign requests](#receiving-campaign-requests) | ||
3. [API Access](#api-access) | ||
4. [Syncing Lists](#syncing-your-lists) | ||
5. [Configuring DNS](#configuring-dns) | ||
6. [Publisher Header/Footer](#publisher-header-and-footer) | ||
7. [Best practices](#best-practices) | ||
|
||
|
||
<br /> | ||
|
||
## Overview | ||
|
||
Traverse Email Retargeting allows marketers to trigger sending publisher-branded email advertisements to your subscribers. | ||
Traverse Email Retargeting allows marketers to trigger sending publisher-branded email advertisements to your subscribers. Traverse sends the email on your behalf and tracks engagement while managing complaints and unsubscribes. | ||
|
||
|
||
<br /> | ||
|
||
## Getting started | ||
|
||
To get started with Traverse Email Retargeting: | ||
|
||
1. [Review the best practices](#best-practices). | ||
2. [Get credentials](#security). | ||
3. [Sync your subscribers](#syncing-your-subscribers). | ||
4. [Consume campaign requests](#consume-campaign-requests). | ||
1. [Get credentials](#api-access). | ||
2. [Sync your lists](#syncing-your-lists). | ||
3. [Configure your DNS](#configuring-dns). | ||
4. [Provide your branded header/footer](#publisher-header-and-footer). | ||
|
||
|
||
<br /> | ||
|
||
## API Access | ||
|
||
## Security | ||
All API calls are authorized via <a href="https://tools.ietf.org/html/rfc6750">OAuth 2.0 bearer tokens</a>. To authenticate a request, the access token must be passed with the `Authentication` header, like so: `Authentication: Bearer {your-bearer-token-here}` | ||
|
||
All API calls are authorized via <a href="https://tools.ietf.org/html/rfc6750">OAuth 2.0 bearer tokens</a>. | ||
|
||
Please <a href="mailto:Traverse Operations <operations@traversedlp.com>">contact us</a> for a token. | ||
|
||
## Best practices | ||
|
||
While we make every attempt to maintain the availability of our system, unexpected errors may occur: | ||
<br /> | ||
|
||
1. Always check whether the HTTP status code is *<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success">2xx</a>* (success) before proceeding, and abort if not. | ||
2. If the status code is *<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error">4xx</a>* (client error), your request is likely invalid. Review the documentation before retrying. | ||
3. If the status code is *<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_Error">5xx</a>* (server error), there is likely a problem on our end. Please retry after 60 seconds. | ||
4. Otherwise, treat any unexpected response, status code, timeout or exception as a *5xx*. | ||
5. Log your requests and replies, and monitor for and review any failures. | ||
## Syncing Your Lists | ||
|
||
Most campaigns will have two associated lists--a subscription list for individuals you would like to mail, and a suppression list for those who should be excluded. The subsription list is hosted by Traverse and periodically updated by the publisher. There are a number of different ways to set up the suppression list, and your capabilities here will determine specifics about the rest of the integration. | ||
|
||
To sync your lists: | ||
|
||
1. [Determine your integration type.](#integration-types) | ||
2. [Configure your suppression list.](#configuring-your-suppression-list) | ||
2. [Create a subscriber list.](#creating-a-list) | ||
2. [Upload your current subscribers in batch.](#adding-subscribers-batch) | ||
3. [Connect us to a feed of your new subscribers.](#adding-subscribers-Individual) | ||
|
||
### Types of Integrations | ||
|
||
Traverse supports working with suppression lists in a number of different ways. A publisher's integration type will depend on which method they are able to support. | ||
|
||
- __Subscription Lookup:__ | ||
|
||
This is the preferred method of integration. The suppression list is hosted and maintained by the publisher, who provides Traverse with a [subscription lookup endpoint](subscription-lookup-endpoint). The publisher provides Traverse with an inclusion list of hashed emails (both MD5 and SHA1), and uses Traverse's [recipient endpoint](#adding-subscribers-individual) to include more recipients after the initial bulk upload. | ||
|
||
- __Traverse-Hosted:__ | ||
|
||
Traverse hosts the suppression list and the publisher updates this list programmatically. This requires the publisher to upload the initial subscriber list and make updates with plaintext emails rather than hashes. The supression list and updates can be either plaintext emails or email hashes. | ||
|
||
- __3rd Party:__ | ||
|
||
Publisher provides Traverse access to a 3rd party unsubscribe service such as UnsubCentral or the publisher's existing ESP. The recipients on your subscription list may need to be in plaintext depending on how this 3rd party service is implemented. Please <a href="mailto:Traverse Operations <operations@traversedlp.com>">reach out</a> to Traverse operations to discuss the specifics of your 3rd party service before putting together the initial subscriber list. | ||
|
||
|
||
### Configuring Your Suppression List | ||
|
||
For an integration that will use a __Traverse-Hosted__ suppression list, follow the steps in the ["Creating a List"](#creating-a-list) section below twice (once each for the subscription and suppression lists). Publishers using a __Subscription Lookup__ integration will follow the directions for building out a [Suppression Lookup Endpoint](#suppression-lookup-endpoint), and then continue on to [create a list](#creating-a-list) | ||
|
||
#### Suppression Lookup Endpoint | ||
|
||
A subscription lookup endpoint should allow Traverse to provide an email hash in an HTTP request, and should respond with the subscription status of the corresponding recipient. When Traverse wants to dispatch a message to a potential recipient, we use this endpoint to look up their details, and then dispatch the message. | ||
|
||
The HTTP endpoint should allow for an email hash to be provided like so. Ideally, the endpoint could look up an email based on either SHA1 or MD5 hash. | ||
|
||
## Syncing your subscribers | ||
`https://www.publisher.com/subscription/lookup?md5={md5-hashed-email}` | ||
|
||
To sync your subscribers: | ||
OR | ||
|
||
1. [Create a subscriber list](#creating-a-subscriber-list). | ||
2. [Connect us to a feed of your new subscribers](#adding-subscribers). | ||
2. [Upload the rest of your subscribers in batch](#adding-subscribers). | ||
`https://www.publisher.com/subscription/lookup?sha1={sha1-hashed-email}` | ||
|
||
### Creating a subscriber list | ||
This endpoint should return at minimum the plaintext email address, first name, which lists they're currently mailable under, if any, and the CAN-SPAM information (IP, timestamp) for each. The response should be in JSON, and consist of an Array of Objects, each describing a subscription: | ||
|
||
``` | ||
[ | ||
{ // First subscription | ||
email: 'foo@bar.com', | ||
firstName: 'John', | ||
listId: 'lifescript_list_id_1', | ||
ip: '1.2.3.4' | ||
timestamp: '2017-07-07T21:27:02+00:00' // ISO-8601 is great. | ||
}, | ||
{ // Another subscription | ||
email: 'foo@bar.com', | ||
firstName: 'Jonathan', // Maybe they provided a different name for this list. | ||
listId: 'lifescript_list_id_2', | ||
ip: '2.3.4.5', | ||
timestamp: '2015-03-02T12:18:01+00:00' | ||
} | ||
] | ||
``` | ||
If the recipient is not subscribed to any list, or if the publisher doesn't have a match for the hash: | ||
|
||
``` | ||
[] // (No subscriptions) | ||
``` | ||
|
||
|
||
### Creating a List | ||
|
||
*Creating subscriber lists programmatically is not yet supported.* | ||
|
||
In the meantime, please <a href="mailto:Traverse Operations <operations@traversedlp.com>">contact us</a> and we will provide you a subscriber-list ID. | ||
|
||
### Adding subscribers | ||
|
||
To add subscribers to a list, use the following endpoint: | ||
### Adding Subscribers (Batch) | ||
|
||
The fastest way to get your subscribers to Traverse is by uploading them in bulk, either via Amazon S3 or SFTP. The file should be in CSV or TSV format. While S3 is preferred, SFTP access is provided by request. Please <a href="mailto:Traverse Operations <operations@traversedlp.com>">reach out</a> when your subscribers are ready to be imported. | ||
|
||
### Adding Subscribers (Individual) | ||
|
||
To add a subscriber to a list, use the following endpoint: | ||
|
||
``` | ||
POST https://retargeting.traversedlp.com/v1/lists/{YOUR-SUBSCRIBER-LIST-ID-HERE}/recipients | ||
``` | ||
|
||
The message body should be an array of JSON objects, each with the following properties: | ||
The message body should be an array containing a single JSON object with the following properties: | ||
|
||
| Property | Value | | ||
|------|-------| | ||
|
@@ -73,51 +149,53 @@ For example: | |
[{ | ||
emailMd5Lower: "1105677c8d9decfa1e36a73ff5fb5531", | ||
emailSha1Lower: "ba9d46a037766855efca2730031bfc5db095c654" | ||
}, { | ||
emailMd5Lower: "9e3669d19b675bd57058fd4664205d2a", | ||
emailSha1Lower: "e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98" | ||
}] | ||
``` | ||
|
||
## Consuming campaign requests | ||
|
||
We create a campaign request when an advertiser wants to send a campaign to one of your subscribers. | ||
|
||
There are two ways to consume campaign requests: | ||
<br /> | ||
|
||
1. [Real time](#real-time-campaign-request-listener). | ||
2. [Batch](#batch-campaign-requests). | ||
|
||
### Real-time campaign-request listener | ||
## Configuring DNS | ||
|
||
To receive campaign requests in real-time, create an HTTPS listener and <a href="mailto:Traverse Operations <operations@traversedlp.com>">let us know the URL</a>. | ||
Traverse uses Amazon SES to send email. You will need to make a few minor DNS updates on your end to get things started. | ||
|
||
We will POST JSON objects with the following properties to the URL: | ||
1. __Choose a subdomain to mail from.__ | ||
|
||
| Property | Description | | ||
|----------|-------------| | ||
| `campaignId` | Campaign ID | | ||
| `emailMd5Lower` | MD5 hash of trimmed, lowercased email address | | ||
| `emailSha1Lower` | MD5 hash of trimmed, lowercased email address | | ||
| `advertiserProperties` | Custom advertiser properties (*advanced*) | | ||
This can be any subdomain you are not currently using (i.e. `{subdomain}.{publisher-domain}.com`). | ||
|
||
For example: | ||
2. __Configure the subdomain to receive email.__ | ||
|
||
```json | ||
{ | ||
"campaignId": "6a11644c-690d-4bf3-bb19-4c3efba5a5a5", | ||
"emailMd5Lower": "1105677c8d9decfa1e36a73ff5fb5531", | ||
"emailSha1Lower": "ba9d46a037766855efca2730031bfc5db095c654", | ||
"listIds": ["772823bd-b7be-4d23-bd78-96a577d02765"], | ||
"advertiserProperties": { | ||
"impressionId": "f53f6078-f802-4c98-90ca-e90aa56995ab", | ||
"foo": "bar" | ||
} | ||
} | ||
``` | ||
In order to legally send email, Traverse must be able to receive incoming messages to this subdomain. To facilitate this, set up a CNAME record which points the sending subdomain domain to our receiving domain. The record should look like this: | ||
|
||
*Note:* If the listener does not promptly reply with an HTTP 2xx status code, we may resubmit the request, later. | ||
| Record Name | Record Type | Record Value | | ||
------|-------|-------| | ||
| `{subdomain}.{publisher-domain}.com` | CNAME | srvrt.com | | ||
|
||
### Batch campaign requests | ||
3. __Configure the subdomain to send email.__ | ||
|
||
*Batch campaign requests are not yet supported.* | ||
The final step is to configure your subdomain to demonstrate ownership and configure DKIM. This is handled by configuring a number of TXT records for the domain. These settings are generated | ||
on a per-domain process, so <a href="mailto:Traverse Operations <operations@traversedlp.com>">contact us</a> when you are ready to make the changes. | ||
|
||
|
||
<br /> | ||
|
||
## Publisher Header and Footer | ||
|
||
Publisher provides a header/footer which will contain dynamic advertiser content. Travese needs: | ||
|
||
- html creative, all images | ||
- unsubscribe link | ||
- physical address | ||
|
||
<br /> | ||
|
||
## Best practices | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have a |
||
|
||
While we make every attempt to maintain the availability of our system, unexpected errors may occur: | ||
|
||
1. Always check whether the HTTP status code is *<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success">2xx</a>* (success) before proceeding, and abort if not. | ||
2. If the status code is *<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error">4xx</a>* (client error), your request is likely invalid. Review the documentation before retrying. | ||
3. If the status code is *<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_Error">5xx</a>* (server error), there is likely a problem on our end. Please retry after 60 seconds. | ||
4. Otherwise, treat any unexpected response, status code, timeout or exception as a *5xx*. | ||
5. Log your requests and replies, and monitor for and review any failures. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My impression is that this documentation would be implementation details. There's some overlap with what would be in the "Publisher Field Guide". The other pieces are implementation details. This part is obviously important, but I'm not sure if it is really implementation details.