NAV Navbar
JavaScript PHP Shell HTTP Ruby Python Java Go

You are currently viewing documentation for our newest platform.

For our legacy platform documentation click here

Glossary

Integration Setup

Merchant SDK Javascript

Code Samples

<script>
  window["friendbuyAPI"] = friendbuyAPI = window["friendbuyAPI"] || [];

  // registers your merchant using your merchant ID found in the
  // retailer app https://retailer.fbot.me/settings/general
  friendbuyAPI.merchantId = "REPLACE_WITH_YOUR_MERCHANT_ID";
  friendbuyAPI.push(["merchant", friendbuyAPI.merchantId]);

  // load the merchant SDK and your campaigns
  (function (f, r, n, d, b, u, y) {
    while ((u = n.shift())) {
      (b = f.createElement(r)), (y = f.getElementsByTagName(r)[0]);
      b.async = 1;
      b.src = u;
      y.parentNode.insertBefore(b, y);
    }
  })(document, "script", [
    "https://static.fbot.me/friendbuy.js",
    "https://campaign.fbot.me/" + friendbuyAPI.merchantId + "/campaigns.js",
  ]);
</script>

To the right is the minimal integration to be placed in your site header. The tracking library and its instructions are designed to work asynchronously, so that if any anomalies should occur with friendbuy, there will be no impact to the behavior of your website.

Our friendbuy integration library is compatible with SPA (Single Page Application) design, see the track page section to report page changes.

Namespace consideration

Only the friendbuyAPI variable is to be considered reserved on the window object. The friendbuy library (including its dependencies) is completely encapsulated and is only partially accessible through controlled push(...) calls on the window.friendbuyAPI gateway.

Tracking Events

Tracking Call API

Example Track Call

<script>
  friendbuyAPI.push([
    "track", // this is a track event
    "email_capture", // this is an event capture event
    {
      email: "john.doe@example.com", // the email
      name: "John Doe", // the name (optional)
      age: 55, // the age (custom parameter)
    },
    true, // Send custom parameters to friendbuy
  ]);
</script>

Friendbuy comes with some built-in event tracking settings:

This only means that when you are tracking these events, you are bound to respect a given format. You can also define your own custom event which won't have any restrictions.

Event Metadata

Example Metadata

{
  "metadata": {
    "title": "Welcome to Foo Store - Account page",
    "name": "account page",
    "url": "https://www.foo-store.com/account/user-1234",
    "widgetDisplayName": "widget foo bar baz",
    "origin": "https://www.foo-store.com",
    "pathname": "/account/user-1234"
  },
  "payload": {
    "type": "foo",
    "name": "bar"
  }
}

Every event sends the metadata of the current state. The metadata contains:

An example of metadata format is to the right:

Event Profile

All events must have a profile associated with them. The merchant SDK will always postpone events until a profile has been retrieved from friendbuy's backend.

More information about profile in the attribution documentation (information may not be disclosed in this documentation)

Event Routing

This is the journey of an event (up to our backend public API).

  1. An event is generated in the integration library.
  2. If an event is considered "controlled" (purchase, email_capture ...) the event is validated.
  3. The signed profile is added to the event request (we use pixel tracking).
  4. The event is sent to the public endpoint of our backend.

Event rules by type

Email Capture Event

Email Capture Code Sample

<script>
  friendbuyAPI.push([
    "track",
    "email_capture",
    { email: "john.doe@example.com" },
  ]);
</script>

Email Capture with Optional Name Parameter

<script>
  friendbuyAPI.push([
    "track",
    "email_capture",
    {
      email: "john.doe@example.com",
      name: "John",
    },
  ]);
</script>

Email Capture Custom Parameter Example

<script>
  friendbuyAPI.push([
    "track",
    "email_capture",
    {
      email: "john.doe@example.com",
      subscribed: "yes", // custom parameter
    },
    true, // Send custom parameters to friendbuy
  ]);
</script>
Attribute Type Required Example
email string yes "john.doe@example.com"
name string no "John Doe"

The only required field for an email capture event is the email field. A minimal email capture event is defined as followed:

All events accept additional information but these additional information will not be sent to friendbuy backend unless requested during the tracking call. If you want additional data to be sent to friendbuy, you'll have to add the boolean true to the list of argument passed to track as followed:

This last true parameter will indicate to the merchant SDK that any additional custom fields you would like to track (in this case subscribed) need to be added to the event payload. This can be useful for example if a reward configuration requires additional information not provided by the event by default.

Customer Event

Minimal Customer Payload

{
  "id": "customer-123",
  "email": "john.doe@example.com"
}

Complete Customer Payload

{
  "id": "customer-123",
  "email": "john.doe@example.com",
  "firstName": "John",
  "lastName": "Doe",
  "isNewCustomer": false,
  "customerSince": "2020-06-12T17:58:44.000Z",
  "loyaltyStatus": "in",
  "age": 26
}

Customer Payload with Custom Parameters

<script>
  friendbuyAPI.push([
    "track",
    "customer",
    {
      email: "john.doe@example.com",
      id: "customer-123",
      name: "John",
      category: "vip",
    },
    true,
  ]);
</script>
Attribute Type Required Example
id string yes "c42526a0-86bb-4b2b-8015-3c88e5502fb3"
email string yes "john.doe@example.com"
name string no "John Doe"
firstName string no "John"
lastName string no "Doe"
isNewCustomer boolean no false
customerSince string no "2020-06-12T17:58:44.000Z"
age integer no 26
loyaltyStatus string no "in", "out, or "blocked"

You can track a customer using the track customer endpoints. Track customer requires a least both an id and a valid email. You may also add the isNewCustomer information.

If you want to provide additional information you must add the boolean true as last argument

Purchase Event

Minimal Purchase Payload

<script>
  friendbuyAPI.push([
    "track",
    "purchase",
    {
      id: "order-123",
      amount: 57.87,
      currency: "USD",
    },
  ]);
</script>

Detailed Purchase Payload

<script>
  friendbuyAPI.push([
    "track",
    "purchase",
    {
      id: "order-123",
      amount: 57.87,
      currency: "USD",
      isNewCustomer: true,
      couponCode: "abc-123",
      customer: {
        email: "john.doe@example.com",
        name: "John Doe",
        id: "customer-123",
        category: "vip",
        age: 32,
        customerSince: "2020-06-12T17:58:44.000Z",
      },
      products: [
        { sku: "PLU-8542", quantity: 4, price: 5.54, name: "flowers" },
        { sku: "PLU-8751", quantity: 3, price: 9.48, name: "chocolates" },
      ],
    },
  ]);
</script>
Attribute Type Required Example
id string yes "ORD-4586"
amount number yes 55.50
currency string yes "USD"
isNewCustomer boolean no false
couponCode string no "abcd1234"
giftCardCodes array no ["abc-123", "xyz-456"]

Purchase accepts a sub-attribute customer. The required fields below are only required if customer data is provided.

Customer sub-attribute Type Required Example
customer.id string yes "CUST-3821"
customer.email string yes "john.doe@gmail.com"
customer.name string yes "John Doe"
customer.isNewCustomer boolean no false
customer.customerSince string no "2020-06-12T17:58:44.000Z"
customer.age integer no 26

and a sub-attribute products (as an array of objects)

Products sub-attribute Type Required Example
products[0].sku string no "PLU-8324-187" or default to "unknown"
products[0].name string no "Yellow Jacket
products[0].quantity number yes 5
products[0].price number yes 28.99
products[0].description string no "Test Product"
products[0].category string no "Apparel"
products[0].url string no "https://example.com/apparel"
products[0].imageUrl string no "https://example.com/images/1234"

Purchase event are the most common conversions.

Product Event

Minimal Product Format

{
  "sku": "sku-123",
  "name": "Potatoes"
}

Minimal Product Payload Example

<script>
  friendbuyAPI.push(["track", "product", { sku: "sku-123", name: "Potatoes" }]);
</script>

Detailed Product Payload Example

<script>
  friendbuyAPI.push([
    "track",
    "product",
    {
      sku: "sku-potats",
      name: "Potatoes",
      price: 0.51,
      currency: "USD",
      category: "vegetables",
      url: "https://www.example.com/product/potats",
      imageUrl: "https://static.example.com/mr-potatoe.jpg",
    },
  ]);
</script>
Attribute Type Required Example
sku string yes "PLU-846871"
name string yes "Yogurt"
price number no 10.52
currency string yes if price "USD"
category string no "dairy"
url string no "https://www.example.com/product/846871"
imageUrl string no "https://static.example.com/product-846871.jpg"
description string no "Plain yogurt"

We allow a merchant to capture a product view using this controlled event capture method.

Page Event

Example Page Event

<script>
  friendbuyAPI.push(["track", "page", { name: "user account" }]);
</script>
Attribute Type Required Example
name string yes "product page"

Page event allows you to track the page name. The page name simplifies targeting vs URLs which often requires wildcards. A page event payload only requires a name

Sign Up Event

Example Sign Up Event

<script>
  friendbuyAPI.push([
    "track",
    "sign_up",
    {
      email: "john.doe@example.com",
      id: "user-123",
      age: 40,
    },
  ]);
</script>
Attribute Type Required Example
id string yes "CUST-8348"
email string yes "john.doe@example.com"
name string no "John"
age integer no 40
loyaltyStatus string no "in", "out, or "blocked"

When a user creates an account, you can register this event using the sign_up event type. Note that a signup event will consider the user to be a new user (as opposed to a track customer event). The controlled fields for a sign up event are id, email, name, campaignId.

Custom Event

Example Custom Event

<script>
  friendbuyAPI.push([
    "track",
    "video-viewed",
    {
      id: "welcome-new-user-video",
      userId: "user-123",
      email: "john.doe@example.com",
      deduplicationId: "user-123:welcome-new-user-video",
    },
  ]);
</script>

In addition to the previous "controlled" events, you may decide to add your own custom event. For example you could trigger a "video viewed" custom event at the end of a marketing video or "survey taken" at the end of a quiz.

Note that a custom event will always send all the information it receives.

When creating a custom event, we strongly recommend passing in a unique deduplicationId. This property must be a string. We will not reward any subsequent custom events with the same type and deduplicationId. You can use any string you prefer as the deduplicationId, as long as it is unique. A unique identifier that directly ties to a specific event is recommended. Examples include: Phone numbers for a phone number capture event, email address for an email capture event. That way, when the phone number or email capture event is submitted more than once, the same identifier is used for each event

Tracking Call Examples

Tracking Customer

Tracking Customer Example

<script>
  friendbuyAPI.push([
    "track",
    "customer",
    {
      id: "customer-1",
      email: "john.doe@example.com",
      firstName: "John",
      lastName: "Doe",
    },
  ]);
</script>

You may provide the customer's information on the widget using a track customer call. This reduces friction during the sharing process by pre-filling these fields in the widget.

Tracking Email

Tracking Email Example

<script>
  friendbuyAPI.push(["track", "email", { email: "john.doe@example.com" }]);
</script>

If you were to only know the email of the visitor, you can use the track email command which only requires an email to be captured.

Tracking Pages

Tracking Page Example

<script>
  friendbuyAPI.push(["track", "page", { name: "home" }]);
</script>

You can name your pages to simplify widget display triggers and analytics. To do so, make sure the page you want to track includes the merchant SDK integration code above.

We recommend naming pages like "product", "homepage", "post-purchase"

Tracking Purchase

Tracking Purchase Example

<script>
  friendbuyAPI.push([
    "track",
    "purchase",
    { id: "order-1", amount: 55.45, currency: "USD" },
  ]);
</script>

Tracking a purchase requires a few mandatory fields:

This would be a minimal purchase track call:

New customer tracking

Purchase with New Customer Example

<script>
  friendbuyAPI.push([
    "track",
    "purchase",
    { id: "order-1", amount: 55.45, currency: "USD", isNewCustomer: true },
  ]);
</script>

If the purchase was made by a new customer, you can add this information to the tracking event. By default we will attempt to discover if the customer is to be considered a new customer. You may override that process by providing the isNewCustomer field.

Tracking purchase customer

Purchase with Customer Example

<script>
  friendbuyAPI.push([
    "track",
    "purchase",
    {
      id: "order-1",
      amount: 55.45,
      currency: "USD",
      customer: {
        id: "customer-1",
        email: "jon.doe@example.com",
      },
    },
  ]);
</script>

Optionally, you can also track purchase's customer, in which case, the customer id and the customer's email would be required

Tracking purchase products

Purchase with Products Example

<script>
  friendbuyAPI.push([
    "track",
    "purchase",
    {
      id: "order-1",
      amount: 55.45,
      currency: "USD",
      isNewCustomer: true,
      couponCode: "abc-123",
      customer: {
        id: "customer-1",
        email: "jon.doe@example.com",
      },
      products: [
        {
          name: "Cool Widget", // name is optional
          sku: "product-1",
          price: 20,
          quantity: 2,
        },
      ],
    },
  ]);
</script>

Finally, you can also add the products being purchased, in which case, the product sku, price and quantity will be required and should be contained in an array. This would give you a rich purchase tracking event as such:

Track Signup

Track Signup Example

<script>
  friendbuyAPI.push([
    "track",
    "sign_up",
    {
      email: "john.doe@example.com",
      name: "John",
      id: "customer-2",
    },
  ]);
</script>

To track a new subscription to your services, you may use the track signup call.

Event Subscriptions

In addition to tracking events and loading widgets, friendbuy's javascript can also be used to establish event listeners on some browser-based friendbuy events.

The currently supported event subscriptions are:

The callback parameter in the event subscription command is a function that will receive different values depending on the type of event. This function will be called in response to the subscribed event being triggered.

couponReceived

Coupon Received Format

<script>
  friendbuyAPI.push(["subscribe", "couponReceived", callback]);
</script>

Example Coupon Received Payload

"20%-off-code"

Example Coupon Received Invocation

<script>
  friendbuyAPI.push([
    "subscribe",
    "couponReceived",
    function (coupon) {
      console.log(coupon); // "20%-off-code"
      // Perform additional actions, like automatically
      // applying coupon code to next purchase.
    },
  ]);
</script>

The couponReceived event is triggered whenever a coupon is distributed to the user through a friendbuy widget. The callback function will receive the coupon code string that was distributed as its only argument.

emailShareSuccess

Email Share Success Format

<script>
  friendbuyAPI.push(["subscribe", "emailShareSuccess", callback]);
</script>

Example Email Share Success Payload

{
  "email": "test@example.com",
  "campaignId": "4eb66e61-c466-45d7-b53d-52183217b28e",
  "widgetId": "ed317d7a-5546-4d2c-a3cc-52e1f5e5ae1b"
}

Example Email Share Success Invocation

<script>
  friendbuyAPI.push([
    "subscribe",
    "emailShareSuccess",
    function (share) {
      console.log(share);
      // Perform additional actions,
      // like sending the share to an analytics tool.
    },
  ]);
</script>

The emailShareSuccess event is triggered whenever an advocate sends an email share through a friendbuy widget. The callback function will receive the email of the advocate, as well as the ids of the campaign and widget used to send the share.

Property type Description
email string The email of the advocate.
campaignId string The id of the campaign the share came from.
widgetId string The id of the widget the share came from.

widgetActionTriggered

Widget Action Triggered Format

<script>
  friendbuyAPI.push(["subscribe", "widgetActionTriggered", callback]);
</script>

Example Widget Action Triggered Payload

{
  "actionName": "facebookShare",
  "campaignId": "46acc817-5ca9-4ab9-a597-c8c6dadadc03",
  "email": "test@example.com",
  "screenName": "Facebook Screen",
  "componentName": "Facebook CTA",
  "widgetConfigId": "41c55c45-eb9f-472d-a403-f1395cbeb601"
}

Example Widget Action Triggered Invocation

<script>
  friendbuyAPI.push([
    "subscribe",
    "widgetActionTriggered",
    function (action) {
      console.log(action);
      // Perform additional actions,
      // like sending the action to an analytics tool.
    },
  ]);
</script>

The widgetActionTriggered event is triggered when a user performs specific actions in the widget, including: clicking a share button, changing screens, submitting their email, copying their personal url, etc. The callback function will receive the following:

Property type Description
actionName string The name of the action being performed. For example: friendEmailCaptured, advocateEmailCaptured, widgetClosed, emailShare, copyText, twitterShare, facebookShare, smsShare, messengerShare, etc. Note the action names may very depending on how your widget is set up.
campaignId string The id of the campaign the action came from.
email string The email of the user performing the action.
screenName string The name of the screen the action occured on. This is deteremined by the name given to the screen in the widget builder.
componentName string The name of the component that triggered the action, as defined in the widget builder. Give your buttons and other components descriptive names for the best effect.
widgetConfigId string The id of the widget the action came from.

Visitor Status

Format

<script>
  friendbuyAPI.push(["getVisitorStatus", callback]);
</script>

Example Invocation

<script>
  friendbuyAPI.push([
    "getVisitorStatus",
    function (status) {
      console.log(status);
      // Do something based on the visitor status data
    },
  ]);
</script>

Example responses

Invalid referral (self-referral detected)

{
  "status": "success",
  "payload": {
    "referralCode": "csb5ag6y",
    "referralCodeBlocked": false,
    "isSelfReferral": true
  },
  "signature": "As+Q8yayyFMGVjRLQ494s7DebeWnB2mWWB36CdYRxF8="
}

Valid referral

{
  "status": "success",
  "payload": {
    "attributionId": "964224f0-c22c-46eb-a0c4-6b20f11bddfb",
    "campaignId": "e69b367f-d6a5-42b6-a438-56d837ffd1de",
    "referralCode": "8yykmns3",
    "referralCodeBlocked": false,
    "isSelfReferral": false,
    "advocate": {
      "customerId": "9843534588704",
      "firstName": "Sam"
    }
  },
  "signature": "ZpQV4uZAPLl0hOdqsLpTen9AoWOcWqfGYI9VPFZbgR8="
}

Visitor Status allows friendbuy to pass details about a user visiting your website to a callback function. This data includes whether the visitor has clicked on a friendbuy referral link into the site, and if so, the source of the click, whether or not the click is a self-referral, and whether or not the referral code is blocked.

The callback parameter in the getVisitorStatus command is a function that will receive an object containing the visitor status payload and a signature to verify the authenticity of the payload.

Common Use Cases for Visitor Status:

Depositing a session-based credit into a referred user’s shopping cart.

Determining if a friend offer email capture widget should be shown.

Obtaining and storing the referral code for for future use, such as in a call to the POST /purchases API endpoint.

Advocate’s first name and customer ID are provided so you can personalize a message that the friend receives after clicking on a referral link.

Verifying the Visitor Status Payload

You may wish to distribute rewards or do some other desirable action for the user based on their visitor status response. To prevent fraud you can verify the payload validates against the signature provided in the response.

See Signature Validation for instructions on validating the signature.

Webhooks

Retry Behavior

When a Webhook receives a status code that is not a 200, we will attempt to retry the request every 15 minutes until 24 hours have passed or a response code of 200 is received.

Validating the Payload

You can verify the authenticity of a webhook request from friendbuy by analyzing its cryptographic signature. When friendbuy sends a request to your endpoints, a signature is placed in the X-Friendbuy-Hmac-SHA256 header, and is computed by Base64 encoding the HMAC-SHA1 hash of the request body with your friendbuy secret key.

See Signature Validation for instructions on validating the signature.

Reward Webhook

Example Payload

{
  "id": "255e4e45-446d-499d-a680-44ab1eca73fb",
  "type": "advocateReward",
  "data": [
    {
      "rewardId": "73cb50ea-7ac8-4f90-9fe4-f5450866f3c0",
      "rewardType": "discount",
      "rewardUnit": "USD",
      "emailAddress": "test@example.com",
      "rewardAmount": "20.00",
      "createdOn": "2019-11-05T01:07:36.720Z",
      "customerId": "asd123-abcfasdf",
      "couponCode": "test-coupon-code",
      "rewardTrigger": "purchase"
    }
  ],
  "createdOn": "2019-11-05T01:07:38.509Z"
}

A reward is created after a conversion is evaluated and determined to be rewardable (i.e. all business rules and fraud checks have been met and the reward falls into a specific tier).

The Reward Webhook is the preferred method for depositing credit or points into an customer's account in your system.

There are two types of Reward Webhooks that can be enabled in your account: Advocate Reward Webhooks and Loyalty Reward Webhooks.

Advocate Reward Webhooks are issued when a referred friend successfully converts and earns a reward. These webhooks represent a reward issued to the advocate who had successfully referred a friend who had then converted using Friendbuy's infrastructure.

Loyalty Reward Webhooks are issued when a loyalty customer successfully completes a loyalty earning event and earns a reward. These webhooks represent a reward issued to the loyalty customer.

In either case, after a reward is created, friendbuy will send a POST request to your system with data about the reward.

The payloads are the same for both Advocate Reward Webhooks and Loyalty Reward Webhooks, but we accept different endpoints for each for ease of use. If you wish to use the same endpoint for both, the type property can be used to identify if a reward webhook is an advocateReward or loyaltyReward.

Payload

Property type Description
id string The id of the webhook. Useful for troubleshooting.
type string Indicates whether the reward is an advocateReward or a loyaltyReward.
createdOn ISO timestamp The date and time the webhook request was made.
data array of objects An array of webhook payloads, see definition below. Multiple rewards may fire in the same webhook if they happen in quick succession.

Reward details will be available in the data property of the request with the following format:

Property Type Description
rewardId string The id of the reward. Useful for troubleshooting and preventing duplicate reward distributions.
rewardType string The type of the reward. One of "discount", "credit", "giftCard", "cash", "product", "ledger", "integration", or"other"``
rewardUnit string The unit of the reward applicable to the rewardType. Typically a currency code (e.g. "USD") or percent ("%").
customerId string The customer id of the customer to be rewarded, if provided. Note: this is your customer ID provided to friendbuy through the javascript integration or MAPI, not an internal ID generated by friendbuy.
emailAddress string The email address of the customer to be rewarded.
rewardAmount number The numerical value of the reward. Typically the value of the coupon or the amount of credit to deposit.
createdOn ISO timestamp The date and time the reward was created.
couponCode string or null The coupon code that was distributed with this reward, if any.
rewardTrigger string The type of event that triggered the reward.
rewardInfo string Specifications about custom rewards, such as "Free Gift."

Email Capture Webhook

Example Payload

{
  "id": "255e4e45-446d-499d-a680-44ab1eca73fb",
  "type": "emailCapture",
  "data": [
    {
      "eventId": "e6c720d4-b721-4789-a110-0d680777b802",
      "emailAddress": "john.customer@example.com",
      "name": "John Customer",
      "campaign": {
        "id": "8a7b9436-8b91-4022-b830-d405dfcc3964",
        "name": "Spring Campaign"
      },
      "referral": {
        "channel": "purl",
        "code": "7p9axss2"
      },
      "advocate": {
        "email": "sarah.advocate@example.com",
        "name": "Sarah Advocate"
      },
      "attributionId": "fea9b87a-9411-4a10-aa41-aa137a09849d",
      "incentive": {
        "couponCode": "Test couponCode",
        "amount": 30,
        "currency": "USD"
      }
    }
  ],
  "createdOn": "2019-11-05T01:07:38.509Z"
}

An email capture is created when someone enters their email into a friend incentive widget or the email gate of a referral widget and checks the opt-in checkbox.

The email capture webhook can be used to funnel these emails into your system to add them into your mailing list or for internal record keeping amongst other uses.

After an email capture is created, Friendbuy will send a POST request to your system with data about the captured email.

NOTE: The email capture widget will only fire if someone checks the opt-in checkbox before submitting their email address.

Payload

Property Type Description
id string The id of the webhook. Useful for troubleshooting.
type "emailCapture" Indicates that this is an email capture request.
createdOn ISO timestamp The date and time the webhook request was made.
data array of objects An array of webhook payloads, see definition below. Multiple email captures may be sent in the same webhook call if they happen in quick succession.

Email Capture details will be available in the data property of the request with the following format:

Property Type Description
eventId string The id of the email capture event. Useful for troubleshooting.
emailAddress string The email address entered into the email field.
name string The name entered into the email capture widget.
campaign object The campaign details for the campaign the email was captured with.
referral object Details about the referral for a referred friend.
advocate object Details about the advocate for a referred friend.
attributionId string The id of the attribution that connects the advocate and the friend.
incentive object The incentive associated with the email capture, if any.

The campaign object in the payload has the following structure:

Property Type Description
id string The id of the campaign used to capture the email.
name string The name of the campaign used to capture the email.

The referral object in the payload has the following structure:

Property Type Description
code string The referral code for the referral that resulted in the friends' email address being captured.
channel string The referral channel.

The advocate object in the payload has the following structure:

Property Type Description
email string The email address entered by the advocate when creating the referral.
name string The name entered by the advocate when creating the referral.
customerId string The advocate's customer id, if known.

The incentive object in the payload has the following structure:

Property Type Description
couponCode string The coupon code given to the user for entering their email, if applicable.
amount number The numerical value of the incentive.
currency string The currency of the incentive (i.e. "USD").

Email Opt-Out Webhook

Example Payload

{
  "id": "fd2f5766-8c27-4bfe-b3d3-9f41e186b13e",
  "type": "emailOptOut",
  "data": [
    {
      "emailAddress": "a.friend@example.com",
      "campaignId": "8a7b9436-8b91-4022-b830-d405dfcc3964",
      "campaignName": "Spring Campaign"
    }
  ],
  "createdOn": "2021-06-01T14:28:27.657Z"
}

An email opt-out is created when a friend who receives an advocate share email clicks the unsubscribe link in that email. When this happens, Friendbuy records the opt-out request and will not send any future share emails to that email address for any of your campaigns.

The email opt-out webhook can be used to also notify you when someone opts out of receiving future share emails so that you can add their email address to your own email address opt-out list. If the email opt-out webhook is configured and enabled then, after an email opt-out is created, Friendbuy will send a POST request to your system with data about the opt-out request.

Payload

Property Type Description
id string The id of the webhook call. Useful for troubleshooting.
type "emailOptOut" Indicates that this is an email opt-out request.
createdOn ISO timestamp The date and time the webhook request was made.
data array of objects An array of webhook payloads, see definition below. Multiple opt-outs may be sent in the same webhook call if they happen in quick succession.

Email Opt-Out details will be available in the data property of the request with the following format:

Property Type Description
emailAddress string The email address of the user who entered into the email field.
campaignId string The id of the campaign that the share email was for.
campaignName string The name of the campaign that the share email was for.

Reward Validation Callback

Overview

The Reward Validation Callback feature is used to determine whether or not friendbuy should fulfill the reward for a conversion based on logic in your own system, such as returns or cancellations. This is meant to provide flexibility on top of the fraud checks and reward criteria that Friendbuy provides.

How it Works

When validating a reward, we will make an HTTP POST request to the url provided in the Validation URL configuration of Reward Criteria. The HTTP response code returned by your system will indicate if the reward should be fulfilled or not. A response code of 200 will validate the reward. A response code of 400 will invalidate the reward. Any other response code will result be interpreted as an error and will trigger our retry protocol.

The request body will include details about the purchase that generated the conversion, such as Advocate data, purchase date, order id, and more. The full data included is described below.

Validation Retry Behavior

When the Reward Validation Callback receives a status code that is not a 200 or a 400, we will attempt to retry the request every 15 minutes until 72 hours have passed or the reward is approved or rejected, whichever comes first. If at the end of 72 hours the response code is still something other than 200 or 400, we will reject the reward and note that status as an error.

Validation Payload

Property Type Description
eventType   string The event type that triggered the conversion. "purchase", "email_capture", "sign_up", or "my_custom_event".
recipientType string The role of the user receiving the reward, "advocate", "friend", or "customer"
event object Details about the event that triggered the reward. Described in detail below.
campaignId string The id of the campaign associated with the reward.
advocate object Details about the Advocate who initiated the referral. Described in detail below.
actor object Details about the actor who performed the action. Described in detail below.

advocate

Property Type Description
customerId string The customer ID of the Advocate. Note: this is your customer ID provided to friendbuy through the javascript integration, not an internal ID generated by friendbuy.
email string The email address of the Advocate.
ipAddress string The IP Address of the Advocate.

actor

Property Type Description
customerId string The customer ID of the Actor. Note: this is your customer ID provided to friendbuy through the javascript integration, not an internal ID generated by friendbuy.
email string The email address of the Actor.
ipAddress string The IP Address of the Actor.

purchase (prior to September 2021)

For merchants enrolled in callback validation prior to September 2021, only purchase events are supported with the following payload. Please contact your Customer Success Manager or support@friendbuy.com if you would like to support a non-purchase event.

Property Type Description
eventType string The event type that triggered the conversion. Only purchase events are supported by the Reward Validation Callback.
purchase object Details about the purchase that triggered the reward. Described in detail below.
createdOn ISO timestamp The date and time the event was created.
campaignId string The id of the campaign associated with the reward.
advocate object Details about the Advocate who earned the reward. Described in detail below.

Purchase Payload (Prior to September 2021)

{
  "eventType": "purchase",
  "createdOn": "2019-11-18T23:48:30.017Z",
  "campaignId": "89d78d25-6a33-4873-8b0e-410e3e7c10fa",
  "purchase": {
    "id": "order-66",
    "amount": 100,
    "currency": "USD",
    "isNewCustomer": true,
    "ipAddress": "12.156.140.124",
    "date": "2019-11-18T23:48:30.017Z",
    "email": "test@example.org",
    "customerId": "123",
    "products": [
      {
        "sku": "test-product",
        "name": "Test Product",
        "quantity": 1,
        "price": 10.0,
        "currency": "USD",
        "description": "A test product",
        "category": "Apparel",
        "url": "https://example.org/test-product",
        "imageUrl": "https://example.org/test-product/image.jpg"
      }
    ]
  },
  "advocate": {
    "customerId": "66",
    "email": "britain+test@friendbuy.com",
    "ipAddress": "12.156.140.124"
  }
}

purchase body (prior to September 2021)

Property Type Description
id string Order id of the purchase.
amount number The order total.
currency string The currency of the purchase. For example: "USD", "GBP", "CAD".
isNewCustomer Boolean A true or false value indicating whether the user who made the purchase is a new customer or not.
date ISO timestamp The date and time the purchase was made.
email string The email address of the user who made the purchase.
customerId string The customer id of the user who made the purchase, if provided. Note: this is your customer ID provided to friendbuy through the javascript integration, not an internal ID generated by friendbuy.
products array A list of products purchased. Described in detail below.
ipAddress string The IP Address of the user who made the purchase.
createdOn ISO timestamp The date and time the event was created.

Purchase Payload (September 2021 and beyond)

{
  "eventType": "purchase",
  "recipientType": "advocate",
  "campaignId": "89d78d25-6a33-4873-8b0e-410e3e7c10fa",
  "event": {
    "createdOn": "2019-11-18T23:48:30.017Z",
    "id": "order-66",
    "amount": 100,
    "currency": "USD",
    "isNewCustomer": true,
    "ipAddress": "12.156.140.124",
    "date": "2019-11-18T23:48:30.017Z",
    "products": [
      {
        "sku": "test-product",
        "name": "Test Product",
        "quantity": 1,
        "price": 10.0,
        "currency": "USD",
        "description": "A test product",
        "category": "Apparel",
        "url": "https://example.org/test-product",
        "imageUrl": "https://example.org/test-product/image.jpg"
      }
    ]
  },
  "advocate": {
    "customerId": "66",
    "email": "britain+test@friendbuy.com",
    "ipAddress": "12.156.140.124"
  },
  "actor": {
    "customerId": "67",
    "email": "actor+test@friendbuy.com",
    "ipAddress": "12.34.56.789"
  }
};

event object: purchase (September 2021 and beyond)

Property Type Description
id string Order id of the purchase.
amount number The order total.
currency string The currency of the purchase. For example: "USD", "GBP", "CAD".
isNewCustomer Boolean A true or false value indicating whether the user who made the purchase is a new customer or not.
date ISO timestamp The date and time the purchase was made.
products array A list of products purchased. Described in detail below.
ipAddress string The IP Address of the user who made the purchase.
createdOn ISO timestamp The date and time the event was created.

Product details will be available in the purchase.products property of the request with the following format. Note: All product data is provided to friendbuy by the javascript integration

Property Type Description
sku string The SKU of the product.
name string The name of the product.
quantity number How many of the product were purchased.
price number The price of the product.
currency string The currency of the products price. For example: USD.
description string A description of the product.
category string The category of the product.
url string The url of the product page.
imageUrl string The url of the product image.

event object: sign_up & email_capture

Property Type Description
createdOn ISO timestamp The date and time the event was created.

Example Custom Event Payload

{
  "eventType": "my_custom_event",
  "recipientType": "friend",
  "campaignId": "89d78d25-6a33-4873-8b0e-410e3e7c10fa",
  "event": {
    "createdOn": "2019-11-18T23:48:30.017Z",
    "customerProperty1": "customer property 1",
    "customerProperty2": "customer property 2",
    "customerState": "CA",
    "customer segment": "18-24",
    "customerNumber": 42,
  },
  "advocate": {
    "customerId": "66",
    "email": "britain+test@friendbuy.com",
    "ipAddress": "12.156.140.124"
  },
  "actor": {
    "customerId": "67",
    "email": "actor+test@friendbuy.com",
    "ipAddress": "12.34.56.789"
  }
}

event object: custom

Custom event callbacks include all information sent in the original event payload.

Property Type Description
createdOn ISO timestamp The date and time the event was created.
customerProperties any Any number of custom properties passed in with the event.

Validating the Callback Payload

You can verify the authenticity of a reward validation callback from friendbuy by analyzing its cryptographic signature. When friendbuy sends a request to your endpoints, a signature is placed in the X-Friendbuy-Hmac-SHA256 header, and is computed by Base64 encoding the HMAC-SHA1 hash of the request body with your friendbuy secret key.

See Signature Validation for instructions on validating the signature.

Email Recipient Authorization Callback

Callback Overview

The Email Recipient Authorization Callback is used to determine whether or not Friendbuy is allowed to send a share email based on the recipient's email address. This allows you to apply your own email opt-out rules on top of Friendbuy's unsubscribe system.

Request Payload

When an advocate shares an offer with a friend via the email channel, Friendbuy sends an email message to the friend on the advocate's behalf. Before actually sending the email message, Friendbuy checks to see whether the friend has previously opted-out of receiving share emails and, if so, the email message is not sent. If you have configured an Email Recipient Authorization Callback for your account then, after an email has passed all of Friendbuy's internal checks, we will make an HTTP POST request to the URL you have provided. The body of the request will contain a list of email addresses, as described below.

Example Payload

{
  "id": "4ac0e132-d1d7-4dc1-963f-dfaf9763594c",
  "type": "emailAuth",
  "data": [
    "allowed.friend@example.com",
    "blocked.friend@example.com"
  ],
  "createdOn": "2021-06-01T14:28:14.794Z"
}
Property Type Description
id string A unique ID for the request. Useful for troubleshooting.
type "emailAuth" Indicates that this is an Email Recipient Authorization callback.
data array of strings An array of recipient email addresses.
createdOn ISO timestamp The time the request was sent.

Response Payload

Example Response

["allowed.friend@example.com"]

Friendbuy expects the response to the email recipient authorization callback to be a list of the allowed email addresses. The share email messages for recipients in the returned list of allowed email addresses will be sent, and the share email messages to recipients not in the returned list will be discarded.

Retry Behavior

If the Email Recipient Authorization Callback fails or if it receives a failure response, the sending of those share emails will be temporarily blocked and the callback will be retried later, on Friendbuy's email retry schedule. The delay between tries is 10 minutes, 5 hours, 40 hours, 7 days, and 22 days. If, after six tries the callback is still failing, the emails will not be sent.

Signature Validation

NodeJS Example

export function verifySignature(data, hmacSignature) {
  const providedHmac = Buffer.from(hmacSignature, "utf-8");
  const generatedHash = Buffer.from(
    crypto
      .createHmac("sha256", FRIENDBUY_SECRET_KEY)
      .update(JSON.stringify(data))
      .digest("base64"),
    "utf-8"
  );
  let hashEquals = false;
  try {
    hashEquals = crypto.timingSafeEqual(generatedHash, providedHmac);
  } catch (e) {
    hashEquals = false;
  }
  return hashEquals;
}

You can verify the authenticity of a webhook request, reward validation callback, or visitor status payload from friendbuy by analyzing its cryptographic signature. For webhooks and integrations, when friendbuy sends a request to your endpoints, the signature will be included in the X-Friendbuy-Hmac-SHA256 header. Visitor status includes the signature in the callback data, next to the payload.

The signature is computed by Base64 encoding the HMAC-SHA1 hash of the request body with your friendbuy secret key. Your friendbuy secret key is in the retailer app. Go to Developer Center > Friendbuy code and copy the Secret Key.

To verify the signature:

  1. Calculate an HMAC-SHA-256 composition of the JSON request body:
    HMAC(api_secret, json_body)
  2. Base64 encode the resulting value.
  3. If the Base64 encoded hash matches the signature header, the request is valid.

Customer Authentication

Summary

Code Samples

// Important! Only generate this signature in your site's backend.
const epoch = Math.round(new Date().getTime() / 1000);
const authString = epoch + ":" + customerEmail + ":" + customerUserId;
// Example: epoch + ":test@example.com:57ec28c3-0834-42cc-8522-9ed6dab0e04a";
const signature = sha256.hmac(secretKey, authString);

<script>
  const authString = "[ authString generated from site's backend code ]"; const
  signature = "[ signature generated from site's backend code ]";
  window["friendbuyAPI"] = friendbuyAPI = window["friendbuyAPI"] || [];
  friendbuyAPI.push(["auth", authString, signature]);
</script>;
<?php
$customerEmail = 'customer@example.com';
$customerUserId = 'CUSTOMER123';
$secret = '[your friendbuy secret key]';
$epoch = time();
$authString = $epoch . ':' . $customerEmail . ':' . $customerUserId;
$signature = hash_hmac('sha256', $authString, $secret);
?>

<script>
const authString = "<?php echo $authString; ?>";
const signature = "<?php echo $signature; ?>";

window["friendbuyAPI"] = friendbuyAPI = window["friendbuyAPI"] || [];

friendbuyAPI.push(["auth", authString, signature]);
</script>

Customer Authentication is an additional security measure that enables additional functionality for the end user within Friendbuy’s widgets and integrations. Note that Customer Authentication should only be done after a Customer has already been tracked by Friendbuy. Customer Authentication enables the following features:

Instructions

  1. In order to authenticate a customer, you will need to create an authentication string composed of the following separated by colons:
    • Current epoch time
    • Customer email
    • Customer id
  2. You will then need to create an HMAC SHA256 signature from the authentication string using the Secret Key from your Friendbuy account.
    • NOTE: Never expose your secret key on the frontend. The signature should be calculated by the backend and then passed to the frontend.
  3. Finally, track the authentication using the authentication string and the signature.

Again, never expose your secret key, never calculate the signature on the front end.

Merchant API Guides

API Summary

The Friendbuy Merchant API is a REST API that allows for communication directly with Friendbuy.

Common use cases for the Merchant API are:

Base URL

The base URL for all Friendbuy Merchant API endpoints is https://mapi.fbot.me/v1. For full reference documentation, see Merchant API Details.

Authorization

Example Request Body

{
  "key": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "secret": "95eb1c78-f77e-4c55-828e-17ed3e0163a2"
}

Example Response Body

{
  "tokenType": "Bearer",
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiO...",
  "expires": "2020-03-20T22:58:56.588Z"
}

Summary

The Friendbuy Merchant API uses Bearer Tokens to authorize requests.

To get a Bearer Token for authorization:

  1. Contact Friendbuy support for your key and secret.
  2. Make a POST request to /authorization:
    1. Set the Content-Type header to application/json
    2. The body for the request should be json containing two parameters, access key and secret key
  3. The response will contain a bearer token in the “token” property and the expiration date of the token
  4. You will use this token to authorize any further API requests.

GET Endpoint Specifications

Requirements

Unless otherwise stated, all GET endpoints require either a toDate and fromDate or a pageToken. If a pageToken is provided, the toDate, fromDate, and pageSize are derived from the token.

The toDate and fromDate parameters should be an ISO format date string. For example: "2021-02-23T01:20:14Z".

Example Request with Pagination

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/email-captures?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z&pageToken=eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0 \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response Body with Pagination

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "name": "Test Customer",
      "email": "user@example.com",
      "widgetName": "Friend Incentive Widget",
      "campaignId": "de07e043-0730-4d32-b52c-146ba61cb859",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "ipAddress": "192.168.0.1",
      "emailCaptureType": "friend",
      "newsletterOptIn": true
    }
  ]
}

Pagination

Unless otherwise noted, all of our GET endpoints support pagination using a pageToken query string parameter.

When making the request for the first page, you just need to pass in a fromDate and fromDate. You can also optionally pass in a page size limit as pageSize.

If results are found, the response body will contain a nextPageToken attribute.

For subsequent requests, passing in nextPageToken from the previous response as pageToken will return the next page of results. A response that does not have a nextPageToken and results indicates the end of the query.

Note: While using a page token, date ranges and page sizes will be locked to the initial request.

GET Widget Views

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/widget-views?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 0,
  "results": [
    {
      "customerId": "ad39255f-b7e6-4c8b-baa8-5c7aa0c3e241",
      "email": "user@example.com",
      "widgetName": "Post Purchase Overlay",
      "campaignId": "st27d77a60-c446-4629-81a9-cc2eaa08738ering",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1",
      "widgetType": "advocateShare"
    }
  ]
}

Summary

The GET Widget Views endpoint allows you to retrieve all widget views within a given time frame, optionally filtered by campaignId, widgetName, or widgetType. widgetType can be either advocateShare or emailCapture.

To retrieve widget views, make a GET request to /analytics/widget-views.

View Merchant API details here

GET Shares

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/shares?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "advocateCustomerId": "c9a58f97-7d2c-4cfd-a8e7-ed404038d2b2",
      "advocateEmail": "user@example.com",
      "advocateName": "Test Advocate",
      "channel": "email",
      "referralCode": "abc123",
      "campaignId": "ad39255f-b7e6-4c8b-baa8-5c7aa0c3e241",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1"
    }
  ]
}

Summary

The GET Shares endpoint allows you to retrieve all shares within a given time frame, optionally filtered by campaignId, advocateEmail, advocateCustomerId, or channel. Shares, like many other records, contain a referralCode that is unique to the share. Referral codes can be used to link different types of events together to create a more complete picture of referral behavior.

To retrieve shares, make a GET request to /analytics/shares.

View Merchant API details here

GET Clicks

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/clicks?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 0,
  "results": [
    {
      "advocateCustomerId": "e24b313b-c941-4baf-8762-34b3af8cddee",
      "advocateEmail": "user@example.com",
      "advocateName": "Test Advocate",
      "channel": "purl",
      "referralCode": "abc123",
      "campaignId": "1b9accd7-8ec5-4ff6-8d22-941fdc7338f4",
      "campaignName": "Holiday Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1",
      "destinationUrl": "https://example.com"
    }
  ]
}

Summary

The GET Clicks endpoint allows you to retrieve all valid clicks within a given time frame, optionally filtered by campaignId and/or channel. Clicks, like many other records, contain a referralCode that is unique to the share the click came from. Referral codes can be used to link different types of events together to create a more complete picture of referral behavior.

To retrieve clicks, make a GET request to /analytics/clicks.

View Merchant API details here

GET Signups

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/account-sign-ups?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "customerId": "1b9accd7-8ec5-4ff6-8d22-941fdc7338f4",
      "email": "user@example.com",
      "name": "Test Friend",
      "campaignId": "03bbcf1f-c0d1-4868-af7c-3b65d44a410d",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1",
      "advocateName": "Test Advocate",
      "advocateEmail": "advocate@example.com",
      "advocateCustomerId": "61dbe3d5-8134-4a96-80e4-540f2df678b2",
      "newCustomer": true,
      "referralCode": "abc123",
      "channel": "purl"
    }
  ]
}

Summary

The GET Signups endpoint allows you to retrieve all referral signups within a given time frame, optionally filtered by campaignId, customerId, or email. Signups, like many other records, contain a referralCode that is unique to the share the user clicked on before signing up. Referral codes can be used to link different types of events together to create a more complete picture of referral behavior.

To retrieve signups, make a GET request to /analytics/account-sign-ups.

View Merchant API details here

GET Purchases

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/purchases?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "customerId": "fbdb5742-6fe4-40cb-95da-df8b02708627",
      "email": "user@example.com",
      "name": "Test Customer",
      "campaignId": "abc52d7f-828d-44e4-8b0d-79df62fdae9c",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "ipAddress": "192.168.0.1",
      "advocateName": "Test Advocate",
      "advocateEmail": "advocate@example.com",
      "advocateCustomerId": "da6c99b7-4040-4677-a152-ef7bebc13b99",
      "newCustomer": true,
      "referralCode": "abc123",
      "amount": 50.0,
      "couponCode": "test-coupon-1",
      "products": [
        {
          "sku": "test-product-1",
          "name": "Test Product",
          "quantity": 2,
          "price": 25.0
        }
      ]
    }
  ]
}

Summary

The GET Purchases endpoint allows you to retrieve all referral purchases within a given time frame, optionally filtered by campaignId, customerId, or email. Purchases, like many other records, contain a referralCode that is unique to the share the user clicked on before making the purchase. Referral codes can be used to link different types of events together to create a more complete picture of referral behavior.

To retrieve purchases, make a GET request to /analytics/purchases.

View Merchant API details here

GET Distributed Advocate Rewards

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "createdOn": "2021-02-23T23:18:59Z",
      "rewardType": "Coupon Code",
      "rewardAmount": 10.0,
      "couponCode": "test-coupon-1",
      "trigger": "purchase",
      "advocateEmail": "advocate@example.com",
      "advocateName": "Test Advocate",
      "advocateCustomerId": "4fe0f0cc-14c6-44c3-ba51-dda17412199a",
      "referralCode": "abc123",
      "channel": "facebook",
      "friendEmail": "friend@example.com",
      "friendName": "Test Friend",
      "friendCustomerId": "2a3e06d4-4e99-47c6-b57f-8cb6b86f77ab",
      "campaignId": "5727868f-1a1f-4b26-8104-b8a93b0c30db",
      "campaignName": "Holiday Campaign"
    }
  ]
}

Summary

The GET Distributed Advocate Rewards endpoint allows you to retrieve all rewards that have been distributed to advocates within a given time frame, optionally filtered by campaignId, advocateCustomerId, or advocateEmail. Distributed Advocate Rewards, like many other records, contain a referralCode that is unique to the share the user clicked on before completing the action that triggered the reward. Referral codes can be used to link different types of events together to create a more complete picture of referral behavior.

NOTE This endpoint only returns rewards that we have successfully distributed to advocates. It does not include rewards that have been rejected or rewards distributed to friends. For rewards distributed to friends, use the GET Distributed Friend Incentives endpoint.

To retrieve distributed advocate rewards, make a GET request to /analytics/distributed-advocate-rewards.

View Merchant API details here

GET Distributed Friend Incentives

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/distributed-friend-incentives?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "createdOn": "2021-02-23T23:18:59Z",
      "incentiveType": "Coupon Code",
      "incentiveAmount": 10.0,
      "couponCode": "test-coupon-1",
      "trigger": "purchase",
      "advocateEmail": "advocate@example.com",
      "advocateName": "Test Advocate",
      "advocateCustomerId": "4fe0f0cc-14c6-44c3-ba51-dda17412199a",
      "referralCode": "abc123",
      "channel": "facebook",
      "friendEmail": "friend@example.com",
      "friendName": "Test Friend",
      "friendCustomerId": "2a3e06d4-4e99-47c6-b57f-8cb6b86f77ab",
      "campaignId": "5727868f-1a1f-4b26-8104-b8a93b0c30db",
      "campaignName": "Holiday Campaign"
    }
  ]
}

Summary

The GET Distributed Friend Incentives endpoint allows you to retrieve all incentives that have been distributed to referred friends within a given time frame, optionally filtered by campaignId, friendCustomerId, or friendEmail. Distributed Friend Incentives, like many other records, contain a referralCode that is unique to the share the user clicked on before completing the action that triggered the incentive. Referral codes can be used to link different types of events together to create a more complete picture of referral behavior.

NOTE This endpoint only returns incentives that we have successfully distributed. It does not include incentives that have been rejected.

To retrieve distributed friend incentives, make a GET request to /analytics/distributed-friend-incentives.

View Merchant API details here

GET Email Captures

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/email-captures?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "name": "Test Customer",
      "email": "user@example.com",
      "widgetName": "Friend Incentive Widget",
      "campaignId": "de07e043-0730-4d32-b52c-146ba61cb859",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "ipAddress": "192.168.0.1",
      "emailCaptureType": "friend",
      "newsletterOptIn": true
    }
  ]
}

Summary

The GET Email Captures endpoint allows you to retrieve all emails captured by Friendbuy within a given time frame, optionally filtered by campaignId, emailCaptureType, or email. emailCaptureType can be either advocate or friend. advocate will retrieve all emails captured by the email gate on a referral widget. friend will retrieve all emails captured by friend incentive widgets.

To retrieve email captures, make a GET request to /analytics/email-captures.

View Merchant API details here

GET Email Metrics

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/email-metrics?fromDate=2021-04-07&toDate=2021-04-07&zone=America%2FLos_Angeles&includeSeries=true \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "fromDate": "2021-04-07",
  "toDate": "2021-04-07",
  "zone": "string",
  "shareEmails": {
    "totalOpens": 10,
    "uniqueOpens": 7,
    "uniqueClicks": 13,
    "totalClicks": 15,
    "shares": 14,
    "recipients": 17,
    "delivered": 14,
    "bounced": 0,
    "spam": 0
  },
  "reminderEmails": {
    "totalOpens": 5,
    "uniqueOpens": 2,
    "uniqueClicks": 5,
    "totalClicks": 7,
    "shares": 4,
    "recipients": 4,
    "delivered": 4,
    "bounced": 0,
    "spam": 0
  },
  "series": [
    {
      "date": "2021-04-07",
      "shareEmails": {
        "totalOpens": 10,
        "uniqueOpens": 7,
        "uniqueClicks": 13,
        "totalClicks": 15,
        "shares": 14,
        "recipients": 17,
        "delivered": 14,
        "bounced": 0,
        "spam": 0
      },
      "reminderEmails": {
        "totalOpens": 5,
        "uniqueOpens": 2,
        "uniqueClicks": 5,
        "totalClicks": 7,
        "shares": 4,
        "recipients": 4,
        "delivered": 4,
        "bounced": 0,
        "spam": 0
      }
    }
  ]
}

Summary

The GET Email Metrics endpoint allows you to retrieve all of the share email and reminder email metrics for a given date range and time zone, optionally filtered by campaignId or widgetId. By default, this endpoint will return the sums for emails and reminder emails in the given date range. If you add "includeSeries=true" in the query string, the response will also include a breakdown of the metrics by date.

NOTE: Unlike other GET endpoints, the GET Email Metrics endpoint is an aggregate endpoint. It only accepts whole dates (e.g. "2021-04-05") and not dates with timestamps. Additionally, the GET Email Metrics endpoint does not utilize pagination.

To retrieve email metrics, make a GET request to /analytics/email-metrics.

View Merchant API details here

GET Ledger Heads

Example Request

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads?currency=USD \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

Example Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1024,
  "results": [
    {
      "customerId": "1b9accd7-8ec5-4ff6-8d22-941fdc7338f4",
      "currency": "USD",
      "currentBalance": 100,
      "lastUpdatedOn": "2021-12-01T23:03:10.783Z"
    },
    ...
  ]
}

Summary

The GET Ledger Heads endpoint allows you to retrieve the current account credit or point balance for all of your customers for a given currency.

A ledger head represents the current account credit or points balance for a given customer at the time of request.

NOTE: Unlike other GET endpoints, the GET Ledger Heads endpoint does not accept a toDate and fromDate parameter. It returns the current ledger status for all customers instead.

To retrieve ledger heads, make a GET request to /analytics/loyalty/ledger-heads.

View Merchant API details here

Example Request Body

{
  "email": "test@example.com",
  "campaignId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "widgetId": "ff83c064-0776-4b99-adcc-c2b93af11b78",
  "customerId": "string",
  "firstName": "John",
  "lastName": "Smith",
  "destinationUrlQueryParams": { "vip": true },
  "ipAddress": "127.0.0.1",
  "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
  "seed": "johnsmith"
}

Example Response Body

{
  "link": "https://fbuy.io/alias/johnsmith",
  "referralCode": "johnsmith",
  "createdOn": "2020-01-05T01:07:38.509Z"
}

Summary

The Friendbuy Merchant API can be used to generate a personal referral link for a specific advocate/campaign combination. The email of the advocate and the id of the campaign you want the link to be associated with are required. Additional parameters including customer id, first name, and last name can also be provided to associate additional details with the referral link.

To retrieve a personal referral link, make a POST request to /personal-referral-link. The response will include the personal referral link in the “link” parameter.

You can then distribute this link however you wish. Common use cases involve sending a personal referral link to a subset of customers through email to promote the referral program and retrieving a link to be displayed within a mobile app.

Please note - in the event that you need to generate a large amount of personal referral links, we do provide a batching endpoint which can process up to 10 links in a single request.

Example Request Body

{
  "requests": [
    {
      "email": "test@example.com",
      "campaignId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "widgetId": "ff83c064-0776-4b99-adcc-c2b93af11b78",
      "customerId": "example-customer-id",
      "firstName": "John",
      "lastName": "Smith",
      "destinationUrlQueryParams": { "vip": true },
      "ipAddress": "127.0.0.1",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
      "seed": "johnsmith"
    }
  ]
}

Example Response Body

{
  "purls": [
    {
      "link": "https://fbuy.io/alias/johnsmith",
      "referralCode": "johnsmith",
      "createdOn": "2020-01-05T01:07:38.509Z",
      "email": "test@example.com",
      "campaignId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "customerId": "example-customer-id"
    }
  ]
}

Summary

In the event that numerous personal referral links need to be generated we suggest to use the personal referral link batching endpoint. It allows for sending up to 10 purl requests at once and thereby cuts down on network latency when creating a large amount of purls.

In order to use the purl patching endpoint, make a POST request to /personal-referral-link-batch. The response will include an object with an array of personal referral links in the “response” parameter.

Decoding the Attribution ID

Code Samples

// This example uses KJUR open source cryptographic library
<script src="https://kjur.github.io/jsrsasign/jsrsasign-latest-all-min.js"></script>;

// Validate fbuy data with public key
const urlParams = new URLSearchParams(window.location.search);
const fbuy = urlParams.get("fbuy");

const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCv+UDAAmI0GyM9obO1P+N8LGfI
If6m+LgQirR1fQLTcQyu+lrQkqa+BhVa/nouoiPm+ZUKVtFMJJ44xxa4OPvXv3tB
UPyhJJGYvA8ARqXedzXo13AvSmhKBKG1LxpdU1KGTQNj9En7dmlyeXF5UXAddqoo
JizmTNzQy1wmQw14DwIDAQAB
-----END PUBLIC KEY-----`;

const isValid = KJUR.jws.JWS.verify(fbuy, publicKey, ["RS256"]);

// Decode fbuy data
const decoded = KJUR.jws.JWS.parse(fbuy);
const [
  merchantId,
  profileId,
  globalId,
  attributionId,
  domain,
  epoch,
  customerId,
  email,
] = decoded.payloadPP.split(":");

Summary

An attributionId will link an event, like a purchase or sign up event, to a referral, allowing Friendbuy to attribute the event to the advocate.

When a Friendbuy referral link is followed, Friendbuy adds the GET parameter fbuy to the destination URL. The fbuy parameter contains an encoded string, containing the attributionId as well as other information relating to the referral. The following event tracking endpoints can use this attributionId decoded from the fbuy parameter.

Tracking a Purchase

Example Request Body

{
  "orderId": "test-order-123",
  "email": "user@example.com",
  "customerId": "15534334",
  "firstName": "Test",
  "lastName": "User",
  "amount": 10.0,
  "currency": "USD",
  "isNewCustomer": false,
  "couponCode": "FRIEND-OFFER-244432",
  "attributionId": "2112d0a1-9d65-456e-a168-382ffe76965a",
  "referralCode": "xhaf5hps",
  "products": [
    {
      "sku": "SKU123324",
      "name": "Test Produce",
      "quantity": 1,
      "price": 10.0
    }
  ]
}

Example Response Body

{
  "eventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "createdOn": "2020-03-05T01:07:38.509Z"
}

Summary

The Friendbuy Merchant API can be used to send purchase events to Friendbuy as an alternative or supplement to our Javascript-based pixel tracking. Common use cases include tracking purchases that occur offline and purchases that occur within a mobile app.

When you submit a purchase using the Friendbuy Merchant API, you must submit a unique order id, a customer id, a purchase amount, and the currency the purchase was in. We strongly recommend also passing the email address of the customer who made the purchase. We also recommend passing a value for isNewCustomer, which we use as part of our reward criteria when determining if the advocate should earn a reward.

A key component of tracking a purchase through the Merchant API is the ability to pass in an attribution id, a coupon code, or a referral code with the purchase. If any of these values is present, we will attempt to use the the coupon code, the attribution id, or the referral code (in that order) to establish attribution to the advocate that referred the user making the purchase. NOTE: the coupon code must have been distributed from a Friend Incentive widget in order for Friendbuy to establish attribution.

Finally, product details may be passed to facilitate rewards based on purchasing a specific product. (For example, you should pass the product skus if your campaign uses sku-based rewards.)

To track a purchase, make a POST request to /event/purchase.

Tracking a Signup

Example Request Body

{
  "email": "user@example.com",
  "customerId": "15529938",
  "firstName": "Test",
  "lastName": "User",
  "couponCode": "FRIEND-OFFER-244432",
  "attributionId": "2112d0a1-9d65-456e-a168-382ffe76965a",
  "referralCode": "xhaf5hps"
}

Example Response Body

{
  "eventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "createdOn": "2020-03-05T01:07:38.509Z"
}

Summary

In much the same way that the Friendbuy Merchant API can be used to track purchases, it can also be used to track account signups. Tracking account signups is completely optional, but depending on your campaign settings you may want to track signups if they are an integral part of your referral flow (i.e. you want to reward signups differently than purchases). NOTE: The ability to configure rewards differently for signups is not yet exposed in the Friendbuy Retailer App but can be configured on the backend by Friendbuy.

Tracking a signup through the API requires an email address and a customer id. You can also optionally pass in customer first name and last name, referral code, and coupon code.

As with purchases and custom events, Friendbuy will attempt to establish attribution to an advocate if a coupon code, an attribution id, or a referral code is present.

To track a signup, make a POST request to /event/account-sign-up

Tracking a Custom Event

Example Request Body

{
  "email": "user@example.com",
  "eventType": "recurring_order",
  "customerId": "15529938",
  "isNewCustomer": false,
  "firstName": "Test",
  "lastName": "User",
  "couponCode": "FRIEND-OFFER-244432",
  "attributionId": "2112d0a1-9d65-456e-a168-382ffe76965a",
  "referralCode": "xhaf5hps",
  "deduplicationId": "3fddb07e-5faa-49c3-9133-092c4e9e1dbe"
}

Example Response Body

{
  "eventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "createdOn": "2020-03-05T01:07:38.509Z"
}

Summary

In addition to tracking purchases and signups, Friendbuy also allows you to track custom event types through the API.

Tracking a custom event through the Merchant API works just like tracking a signup, except that you are also required to pass an eventType. The eventType can be any string that you want to use to denote the event you are tracking. You must configure this event type in your campaign settings in order for it to be properly tracked and attributed to a campaign.

As with purchases and signups, Friendbuy will attempt to establish attribution to an advocate if a coupon code, an attribution id, or a referral code is present.

When creating a custom event, we strongly recommend passing in a unique deduplicationId. This property must be a string. We will not reward any subsequent custom events with the same type and deduplicationId. You can use any string you prefer as the deduplicationId, as long as it is unique. A unique identifier that directly ties to a specific event is recommended. Examples include: Phone numbers for a phone number capture event, email address for an email capture event. That way, when the phone number or email capture event is submitted more than once, the same identifier is used for each event

To track a custom event, make a POST request to /event/custom.

Tracking Customer Details

Example Request Body

{
  "email": "user@example.com",
  "customerId": "328989893",
  "isNewCustomer": false,
  "firstName": "Test",
  "lastName": "User",
  "age": 23,
  "gender": "male",
  "zipCode": "90038",
  "state": "CA",
  "city": "West Hollywood",
  "category": "VIP",
  "country": "USA",
  "language": "English"
}

Example Response Body

{
  "eventId": "7b5e9a0a-3386-49c8-84d7-6d4047639285",
  "createdOn": "2020-03-05T01:07:38.509Z"
}

Summary

Many Friendbuy Merchant API endpoints allow for the tracking of limited customer data. In some cases, you may wish to fill in detailed information for all or certain customers. Email and customerId are required values. You can also track the following: isNewCustomer, firstName, lastName, age, gender, zipCode, state, city, category, country, language.

The primary use case of tracking customer details will be to facilitate widget and reward targeting and segmentation when that feature is released in the future.

To track a customer make a POST request to /customer

Request User Data for CCPA/GDPR

Example Requests

GET /user-data?email=test@example.com
GET /user-data?customerId=1554332

Example Response Body

{
  "emails": ["user@example.com", "test@example.com"],
  "names": ["Test User", "Other User"],
  "customerIds": ["1554332"],
  "ipAddresses": ["127.0.0.0.1"],
  "languages": ["English", "Spanish"],
  "userAgents": [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0"
  ],
  "colorDepths": [0],
  "platforms": ["IOS"],
  "screenSizes": ["3072x1920"],
  "trackedEvents": [
    {
      "type": "purchase",
      "url": "https://example.com"
    }
  ],
  "shares": {
    "email": 5,
    "facebook": 1,
    "messenger": 0,
    "sms": 0,
    "twitter": 0,
    "purl": 1
  },
  "conversions": {
    "email": 2,
    "facebook": 0,
    "messenger": 0,
    "sms": 0,
    "twitter": 0,
    "purl": 3
  }
}

Summary

In order to comply with CCPA and GDPR requirements, Friendbuy supports the retrieval of any user data for a given email address or customer id. When a request is made, Friendbuy will return the following data points that we have associated with the email address or customer id:

**To make a request for user data, make a **GET request to **/user-data** providing the email or customer id as a query string parameter.

Deleting User Data for CCPA/GDPR

Example Requests

DELETE /user-data?email=test@example.com
DELETE /user-data?customerId=1554332

Example Response

{
  "task_id": "47fd3e67-8659-42f2-9d03-192d82a48651"
}

Summary

In addition to retrieving user data for CCPA or GDPR, the Friendbuy Merchant API also allows you to request the deletion of user data to fulfill deletion requests from end-users. The response body contains a task_id that can be used for troubleshooting if necessary. All deletion requests run asynchronously, so if the request is successfully registered you will receive a response code of 204. Any other response code indicates an error.

NOTE: Once this request is made any data associated with that email or customer id (as indicated by the GET /user-data endpoint) will be permanently deleted or redacted as appropriate. This action is completely irreversible, so be sure you want to delete this data before making the request.

To request data deletion for a given email address or customer id, make a DELETE request to /user-data providing the email and/or customer id of the user requesting deletion as a query string parameter

Merchant API Details

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Example public API for FriendBuy

Base URLs:

Email: Support License: Apache 2.0

Authentication Scheme

postAuthorization

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/authorization \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json'

POST https://mapi.fbot.me/v1/authorization HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "key": "string",
  "secret": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiO..."
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json'
};

fetch('https://mapi.fbot.me/v1/authorization',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
}

result = RestClient.post 'https://mapi.fbot.me/v1/authorization',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

r = requests.post('https://mapi.fbot.me/v1/authorization', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/authorization', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/authorization");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/authorization", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/authorization

Body parameter

{
  "key": "string",
  "secret": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiO..."
}

Parameters

Name In Type Required Description
key body string(uuid) true Your api access key
secret body string true Your api secret key

Example responses

200 Response

{
  "tokenType": "Bearer",
  "token": "string",
  "expires": "2020-05-07T22:57:03Z"
}

Responses

Name Type Required Restrictions Description
tokenType string false none The type of the token generated (Bearer).
token string(byte) false none The token generated. You will use this to authenticate.
expires string(date-time) false none Expires 20 minutes after being registered.

Response Codes

Status Meaning Description Schema
200 OK Successful authorization request. authorizationResponse
400 Bad Request Invalid input, object invalid Error
401 Unauthorized Unauthorized Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/personal-referral-link \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://mapi.fbot.me/v1/personal-referral-link HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "test@example.com",
  "campaignId": "ef9befc6-18f1-418c-8914-5ee8d09bb5aa",
  "widgetId": "ff83c064-0776-4b99-adcc-c2b93af11b78",
  "customerId": "CUST1234",
  "firstName": "John",
  "lastName": "Smith",
  "destinationUrlQueryParams": {},
  "seed": "johnsmith",
  "channel": "purl",
  "ipAddress": "127.0.0.1",
  "userAgent": "Mozilla/5.0..."
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://mapi.fbot.me/v1/personal-referral-link',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://mapi.fbot.me/v1/personal-referral-link',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://mapi.fbot.me/v1/personal-referral-link', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/personal-referral-link', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/personal-referral-link");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/personal-referral-link", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/personal-referral-link

Create or retrieve a personal URL for a given customer or email address and campaign.

Generate event

Body parameter

{
  "email": "test@example.com",
  "campaignId": "ef9befc6-18f1-418c-8914-5ee8d09bb5aa",
  "widgetId": "ff83c064-0776-4b99-adcc-c2b93af11b78",
  "customerId": "CUST1234",
  "firstName": "John",
  "lastName": "Smith",
  "destinationUrlQueryParams": {},
  "seed": "johnsmith",
  "channel": "purl",
  "ipAddress": "127.0.0.1",
  "userAgent": "Mozilla/5.0..."
}
Name In Type Required Description
email body string(email) true Email of the advocate.
campaignId body string(uuid) true ID of the campaign to use to generate the link.
widgetId body string(uuid) false ID of the widget placement for analytics and reporting.
customerId body string false Your customer id for the advocate.
firstName body string false First name of the advocate.
lastName body string false Last name of the advocate.
destinationUrlQueryParams body object false Custom parameters to be inserted into the url that users are directed to when clicking the link.
seed body string false Specifies what the vanity url will be based on if provided.
channel body string false The share channel the link will be associated with in analytics. Recommended value is "purl".
ipAddress body string false IP Address of the advocate. Used for fraud checks.
userAgent body string false User Agent of the advocate. Used for fraud checks.

Enumerated Values

Parameter Value
channel email
channel facebook
channel generic
channel instagram
channel messenger
channel sms
channel snap
channel twitter
channel purl

Example responses

200 Response

{
  "link": "string",
  "referralCode": "string",
  "createdOn": "string"
}
Name Type Required Restrictions Description
link string true none The referral link that was created.
referralCode string true none Referral code associated with new referral link.
createdOn string(datetime) true none When the link was created

Response Codes

Status Meaning Description Schema
200 OK Personal referral link already exists - returning the pre-existing record. personalReferralLinkResponse
400 Bad Request Invalid input, object invalid Error
404 Not Found Not found - campaign does not exist or is inactive. Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

postPersonalReferralLinkBatch

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/personal-referral-link-batch \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'
POST https://mapi.fbot.me/v1/personal-referral-link-batch HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json
const inputBody = '{
  "requests": [
    {
      "email": "test@example.com",
      "campaignId": "string",
      "widgetId": "string",
      "customerId": "string",
      "firstName": "John",
      "lastName": "Smith",
      "destinationUrlQueryParams": {},
      "seed": "string",
      "prefix": "string",
      "channel": "purl",
      "short": false,
      "ipAddress": "string",
      "userAgent": "api",
      "widgetId": "string",
      "eventUrl": "string",
      "eventPage": "string"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};
fetch('https://mapi.fbot.me/v1/personal-referral-link-batch',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});
require 'rest-client'
require 'json'
headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}
result = RestClient.post 'https://mapi.fbot.me/v1/personal-referral-link-batch',
  params: {
  }, headers: headers
p JSON.parse(result)
import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}
r = requests.post('https://mapi.fbot.me/v1/personal-referral-link-batch', headers = headers)
print(r.json())
<?php
require 'vendor/autoload.php';
$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);
$client = new \GuzzleHttp\Client();
// Define array of request body.
$request_body = array();
try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/personal-referral-link-batch', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }
 // ...
URL obj = new URL("https://mapi.fbot.me/v1/personal-referral-link-batch");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());
package main
import (
       "bytes"
       "net/http"
)
func main() {
    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }
    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/personal-referral-link-batch", data)
    req.Header = headers
    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/personal-referral-link-batch

Create or retrieve a personal URL for a given customer or email address and campaign. The URL provided uses input for seed and prefix from the campaign however those attributes can be overridden by the corresponding attributes within the request body.

Generate event

Body parameter

{
  "requests": [
    {
      "email": "test@example.com",
      "campaignId": "string",
      "widgetId": "string",
      "customerId": "string",
      "firstName": "John",
      "lastName": "Smith",
      "destinationUrlQueryParams": {},
      "seed": "string",
      "prefix": "string",
      "channel": "purl",
      "short": false,
      "ipAddress": "string",
      "userAgent": "api",
      "widgetId": "string",
      "eventUrl": "string",
      "eventPage": "string"
    }
  ]
}

Parameters

Name In Type Required Description
requests body array true Array of PURL requests.
email requests string(email) true Email of the advocate.
campaignId requests string(uuid) true ID of the campaign to use to generate the link.
widgetId requests string(uuid) false ID of the widget placement for analytics and reporting
customerId requests string false Your customer id for the advocate.
firstName requests string false First name of the advocate.
lastName requests string false Last name of the advocate.
destinationUrlQueryParams requests object false Custom parameters to be inserted into the url that users are directed to when clicking the link.
seed requests string false Specifies what the vanity url will be based on if provided.
channel requests string false The share channel the link will be associated with in analytics. Recommended value is "purl".
ipAddress requests string false IP Address of the advocate. Used for fraud checks.
userAgent requests string false User Agent of the advocate. Used for fraud checks.

Enumerated Values

Parameter Value
channel email
channel facebook
channel generic
channel instagram
channel messenger
channel sms
channel snap
channel twitter
channel purl

Example responses

200 Response

{
  "purls": [
    {
      "link": "string",
      "referralCode": "string",
      "createdOn": "string",
      "email": "user@example.com",
      "campaignId": "string",
      "customerId": "string"
    }
  ]
}

Responses

Name Type Required Restrictions Description
link string true none The personal referral link that was created.
referralCode string true none Referral code associated with new referral link.
createdOn string(datetime) true none Timestamp for when the link was created.
email string(email) true none Email for the personal referral link in question.
campaignId string(uuid) true none Campaign ID the personal referral link is associated with.
customerId string false none Customer ID the personal referral link is associated with.

Response Codes

Status Meaning Description Schema
200 OK Successful request, returning either pre-existing or generated personal referral links. personalReferralLinkBatchResponse
400 Bad Request Invalid input, object invalid Error
404 Not Found Not found - campaign does not exist or is inactive. Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

postPurchaseEvent

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/event/purchase \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://mapi.fbot.me/v1/event/purchase HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "orderId": "string",
  "email": "user@example.com",
  "customerId": "string",
  "firstName": "string",
  "lastName": "string",
  "amount": 0,
  "currency": "string",
  "isNewCustomer": false,
  "couponCode": "string",
  "attributionId": "string",
  "referralCode": "string",
  "products": [
    {
      "sku": "string",
      "name": "string",
      "quantity": 0,
      "price": 0
    }
  ],
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0..."
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://mapi.fbot.me/v1/event/purchase',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://mapi.fbot.me/v1/event/purchase',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://mapi.fbot.me/v1/event/purchase', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/event/purchase', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/event/purchase");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/event/purchase", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/event/purchase

Generate purchase event.

Generate purchase event

Body parameter

{
  "orderId": "string",
  "email": "user@example.com",
  "customerId": "string",
  "firstName": "string",
  "lastName": "string",
  "amount": 0,
  "currency": "string",
  "isNewCustomer": false,
  "couponCode": "string",
  "attributionId": "string",
  "referralCode": "string",
  "products": [
    {
      "sku": "string",
      "name": "string",
      "quantity": 0,
      "price": 0
    }
  ],
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0..."
}

Parameters

Name In Type Required Description
orderId body string true Unique order id for the purchase.
email body string(email) false Email of the customer making the purchase.
customerId body string true Customer ID of the customer making the purchase.
firstName body string false First name of the customer making the purchase.
lastName body string false Last name of the customer making the purchase.
amount body number true The order total for the purchase.
currency body string true The currency used for the purchase (i.e. USD).
isNewCustomer body boolean false Whether or not the customer making the purchase has made a previous purchase.
couponCode body string false The coupon code used in the purchase, if any. Can be used to establish attribution with an advocate.
attributionId body string false The attribution ID from the advocate's referral, if any.
referralCode body string false A referral code to be used to establish attribution with an advocate.
additionalProperties body object false Any additional properties you wish to track with the purchase.
additionalProperty additionalProperties string false A key value pair indicating the property name and value.
ipAddress body string false IP address of the customer making the purchase.
userAgent body string false User Agent of the customer making the purchase.
products body product false An array of purchased products.

Product Parameters

Name Type Required Restrictions Description
sku string true none none
name string false none none
quantity integer false none none
price integer false none none

Responses

Example responses

201 Response

{
  "eventId": "string",
  "createdOn": "string"
}
Name Type Required Restrictions Description
eventId string(uuid) true none The Friendbuy id for this event.
createdOn string(datetime) true none When this event was created.

Response Codes

Status Meaning Description Schema
201 Created Post event created purchaseEventResponse
400 Bad Request Invalid input, object invalid Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

postSignUpEvent

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/event/account-sign-up \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://mapi.fbot.me/v1/event/account-sign-up HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "user@example.com",
  "customerId": "string",
  "firstName": "string",
  "lastName": "string",
  "couponCode": "string",
  "attributionId": "string",
  "referralCode": "string",
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0...",
  "timezone": "America/Los_Angeles",
  "loyaltyStatus": "in",
  "birthday": {
    "day": 1,
    "month": 10,
    "year": 1980,
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://mapi.fbot.me/v1/event/account-sign-up',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://mapi.fbot.me/v1/event/account-sign-up',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://mapi.fbot.me/v1/event/account-sign-up', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/event/account-sign-up', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/event/account-sign-up");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/event/account-sign-up", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/event/account-sign-up

Generate sign-up event.

Body parameter

{
  "email": "user@example.com",
  "customerId": "string",
  "firstName": "string",
  "lastName": "string",
  "attributionId": "string",
  "couponCode": "string",
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0...",
  "timezone": "America/Los_Angeles",
  "birthday": {
    "day": 1,
    "month": 10,
    "year": 1980
  }
}

Parameters

Name In Type Required Description
email body string(email) true Email of the user signing up.
customerId body string true Customer id of the user.
firstName body string false First name of the user.
lastName body string false Last name of the user.
couponCode body string false The coupon code used in the sign up, if any. Can be used to establish attribution with an advocate.
attributionId body string false The attribution ID from the advocate's referral, if any.
referralCode body string false A referral code to be used to establish attribution with an advocate.
loyaltyStatus body string false Denotes the customer's loyalty member opt in status. Value can be "in", "out", "blocked".
additionalProperties body object false Any additional properties you wish to track with this signup.
additionalProperty additionalProperties string false A key value pair representing the name of the property and the value.
ipAddress body string false The IP address of the user.
userAgent body string false The User Agent of the user.
timezone body string false Timezone of the customer. See Timezones
birthday body object false Birthday of the customer
day birthday integer true Day the event should trigger. 1 - 31.
month birthday integer true Month the event should trigger. 1 - 12.
year birthday integer false Year the event will trigger (YYYY).

Example responses

201 Response

{
  "eventId": "string",
  "createdOn": "string"
}

Responses

Name Type Required Restrictions Description
eventId string(uuid) true none The Friendbuy id for this event.
createdOn string(datetime) true none When this event was created.

Response Codes

Status Meaning Description Schema
201 Created Post event created signUpEventResponse
400 Bad Request Invalid input, object invalid Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

postCustomEvent

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/event/custom \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://mapi.fbot.me/v1/event/custom HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "user@example.com",
  "eventType": "string",
  "customerId": "string",
  "isNewCustomer": false,
  "firstName": "string",
  "lastName": "string",
  "attributionId": "string",
  "couponCode": "string",
  "deduplicationId": "string",
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0..."
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://mapi.fbot.me/v1/event/custom',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://mapi.fbot.me/v1/event/custom',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://mapi.fbot.me/v1/event/custom', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/event/custom', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/event/custom");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/event/custom", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/event/custom

Generate a custom event where the structure of the general structure of the request body object is defined by the client.

Generate event

Body parameter

{
  "email": "user@example.com",
  "eventType": "string",
  "customerId": "string",
  "isNewCustomer": false,
  "firstName": "string",
  "lastName": "string",
  "couponCode": "string",
  "attributionId": "string",
  "referralCode": "string",
  "deduplicationId": "string",
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0..."
}

Parameters

Name In Type Required Description
email body string(email) true Email of the user performing the event.
eventType body string true The type of the event you are tracking (i.e. "newsletter signup", "video view", etc).
customerId body string false Customer id of the user performing the event.
isNewCustomer body boolean false Whether or not the user is a new customer.
firstName body string false First name of the user.
lastName body string false Last name of the user.
couponCode body string false The coupon code used in the signup, if any. Can be used to establish attribution with an advocate.
attributionId body string false The attribution ID from the advocate's referral, if any.
referralCode body string false A referral code to be used to establish attribution with an advocate.
deduplicationId body string false A unique identifier used to prevent duplication of events. A unique identifier that directly ties to a specific event is recommended. Examples include: Phone numbers for a phone number capture event, email address for an email capture event. That way, when the phone number or email capture event is submitted more than once, the same identifier is used for each event.
additionalProperties body object false Any additional properties you wish to track with the event.
additionalProperty additionalProperties string false A key value pair representing the name and value of the additional property.
ipAddress body string false IP Address of the user.
userAgent body string false User Agent of the user.

Example responses

201 Response

{
  "eventId": "string",
  "createdOn": "string"
}

Responses

Name Type Required Restrictions Description
eventId string(uuid) true none The Friendbuy id for this event.
createdOn string(datetime) true none When this event was created.

Response Codes

Status Meaning Description Schema
201 Created Post event created customEventResponse
400 Bad Request Invalid input, object invalid Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

postCustomer

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/customer \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://mapi.fbot.me/v1/customer HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "email": "user@example.com",
  "customerId": "string",
  "isNewCustomer": false,
  "firstName": "string",
  "lastName": "string",
  "age": 0,
  "gender": "string",
  "zipCode": "string",
  "state": "string",
  "city": "string",
  "category": "string",
  "country": "string",
  "language": "string",
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0...",
  "timezone": "America/Los_Angeles",
  "loyaltyStatus": "in",
  "birthday": {
    "day": 1,
    "month": 10,
    "year": 1980,
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://mapi.fbot.me/v1/customer',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://mapi.fbot.me/v1/customer',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://mapi.fbot.me/v1/customer', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/customer', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/customer");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/customer", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/customer

Add a new customer to our records.

Generate event

Body parameter

{
  "email": "user@example.com",
  "customerId": "string",
  "isNewCustomer": false,
  "firstName": "string",
  "lastName": "string",
  "age": 0,
  "gender": "string",
  "zipCode": "string",
  "state": "string",
  "city": "string",
  "category": "string",
  "country": "string",
  "language": "string",
  "additionalProperties": {
    "property1": "string",
    "property2": "string"
  },
  "ipAddress": "string",
  "userAgent": "Mozilla/5.0...",
  "timezone": "America/Los_Angeles",
  "birthday": {
    "day": 1,
    "month": 10,
    "year": 1980
  }
}

Parameters

Name In Type Required Description
email body string true Email of the customer.
customerId body string true Your id for the customer.
isNewCustomer body boolean false Whether or not the customer has purchased before.
firstName body string false First name of the customer.
lastName body string false Last name of the customer.
age body integer false Age of the customer.
gender body string false Gender of the customer.
zipCode body string false Zip code of the customer.
state body string false State the customer lives in.
city body string false The customer's city.
category body string false The category the customer is in, if any.
country body string false The customer's country.
language body string false The customer's preferred language.
loyaltyStatus body string false Denotes the customer's loyalty member opt in status. Value can be "in", "out", "blocked".
additionalProperties body object false Any additional properties you wish to track with this customer.
additionalProperty additionalProperties string false A key value pair representing the name of the property and its value.
ipAddress body string false IP address of the customer.
userAgent body string false User Agent of the customer.
timezone body string false Timezone of the customer. See Timezones
birthday body object false Birthday of the customer
day birthday integer true Day the event should trigger. 1 - 31.
month birthday integer true Month the event should trigger. 1 - 12
year birthday integer false Year the event will trigger (YYYY).

Example responses

200 Response

{
  "eventId": "string",
  "createdOn": "string"
}

Responses

Name Type Required Restrictions Description
eventId string true none The Friendbuy id for the event to process the customer.
createdOn string(datetime) true none When this customer was created.

Response Codes

Status Meaning Description Schema
200 OK Customer already exists - updated customerResponse
201 Created Customer created customerResponse
400 Bad Request Invalid input, object invalid Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getUserData

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/user-data \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/user-data HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch("https://mapi.fbot.me/v1/user-data", {
  method: "GET",

  headers: headers,
})
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/user-data',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/user-data', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/user-data', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/user-data");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/user-data", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/user-data

Parameters

Name In Type Required Description
email query string(email) false Email of the user.
customerId query string false Your id for the customer.

Example responses

200 Response

{
  "emails": ["user@example.com"],
  "names": ["string"],
  "customerIds": ["string"],
  "ipAddresses": ["string"],
  "languages": ["string"],
  "userAgents": ["string"],
  "colorDepths": [0],
  "platforms": ["string"],
  "screenSizes": ["string"],
  "trackedEvents": [
    {
      "type": "string",
      "url": "string"
    }
  ],
  "shares": {
    "email": 0,
    "facebook": 0,
    "messenger": 0,
    "sms": 0,
    "twitter": 0,
    "purl": 0
  },
  "conversions": {
    "email": 0,
    "facebook": 0,
    "messenger": 0,
    "sms": 0,
    "twitter": 0,
    "purl": 0
  }
}

Responses

Name Type Required Restrictions Description
emails [string] false none none
names [string] false none none
customerIds [string] false none none
ipAddresses [string] false none none
languages [string] false none none
userAgents [string] false none none
colorDepths [number] false none none
platforms [string] false none none
screenSizes [string] false none none
trackedEvents [userDataGetResponse_trackedEvents] false none none
shares userDataGetResponse_shares false none none
conversions userDataGetResponse_shares false none none

Tracked Event Response

Name Type Required Restrictions Description
type string false none The type of the event.
url string false none The url of the page the event was tracked on.

Tracked Share/Conversion Response

The same schema applies to both tracked shares and tracked conversions.

Name Type Required Restrictions Description
email integer false none The number of email shares or conversions.
facebook integer false none The number of facebook shares or conversions.
messenger integer false none The number of messenger shares or conversions.
sms integer false none The number of sms shares or conversions.
twitter integer false none The number of twitter shares or conversions.
purl integer false none The number of purl shares or conversions.

Response Codes

Status Meaning Description Schema
200 OK Successful user data get request. userDataGetResponse
400 Bad Request Invalid input, object invalid Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

deleteUserData

Code samples

# You can also use wget
curl -X DELETE https://mapi.fbot.me/v1/user-data \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

DELETE https://mapi.fbot.me/v1/user-data HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch("https://mapi.fbot.me/v1/user-data", {
  method: "DELETE",

  headers: headers,
})
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.delete 'https://mapi.fbot.me/v1/user-data',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.delete('https://mapi.fbot.me/v1/user-data', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','https://mapi.fbot.me/v1/user-data', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/user-data");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("DELETE");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "https://mapi.fbot.me/v1/user-data", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

DELETE /v1/user-data

Parameters

Name In Type Required Description
email query string(email) false Email for the user.
customerId query string false Your id for the customer.

Example responses

200 Response

{
  "jobId": "string"
}

Responses

Name Type Required Restrictions Description
jobId string(uuid) false none The id of the task to delete the data. Used for troubleshooting if needed.

Response Codes

Status Meaning Description Schema
200 OK Successful user data delete request. userDataDeleteResponse
400 Bad Request Invalid input, object invalid Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

timeBasedRegister

Code samples

# You can also use wget
curl -X POST https://mapi.fbot.me/v1/time-based-event/register \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST https://mapi.fbot.me/v1/time-based-event/register HTTP/1.1
Host: mapi.fbot.me
Content-Type: application/json
Accept: application/json

const inputBody = '{
  "customerId": "string",
  "date": {
    "day": 0,
    "month": 0,
    "year": 0,
    "timezone": "America/Adak"
  },
  "metadata": {},
  "configId": "string"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('https://mapi.fbot.me/v1/time-based-event/register',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post 'https://mapi.fbot.me/v1/time-based-event/register',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('https://mapi.fbot.me/v1/time-based-event/register', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','https://mapi.fbot.me/v1/time-based-event/register', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/time-based-event/register");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "https://mapi.fbot.me/v1/time-based-event/register", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /v1/time-based-event/register

Scheduling an event to be scheduled some time in the future.

Register time based event.

Body parameter

{
  "customerId": "string",
  "date": {
    "day": 0,
    "month": 0,
    "year": 0,
    "timezone": "America/Adak"
  },
  "metadata": {},
  "configId": "string"
}

Parameters

Name In Type Required Description
customerId body string true Customer id of the user.
date body object true The date the event is scheduled.
day date integer true Day the event should trigger. 1 - 31.
month date integer true Month the event should trigger. 1 - 12
year date integer false Year the event will trigger (YYYY).
metadata body object false Any metadata to be included.
configId * body string conditional Id of the configuration. Required if kind is not provided.
kind * body string conditional One of "birthday", "anniversary", "other". Required if configId is not provided.

Example responses

200 Response

{
  "event": {
    "id": "string",
    "configId": "string",
    "merchantId": "string",
    "orphaned": true,
    "createdOn": "string",
    "registryId": "string",
    "customerId": "string",
    "originalDate": {
      "day": 0,
      "month": 0,
      "year": 0,
      "timezone": "America/Adak"
    },
    "expiresDate": {
      "day": 0,
      "month": 0,
      "year": 0,
      "timezone": "America/Adak"
    },
    "expireOn": 0,
    "metadata": {},
    "attempt": 0
  }
}

Responses

Status Meaning Description Schema
200 OK Event is either created or updated (depends on related config). TimeBasedRegisterResponse
400 Bad Request Invalid input, object invalid Error
409 Conflict Conflict Error
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getWidgetViews

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/widget-views?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/widget-views?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/widget-views?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/widget-views',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/widget-views', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/widget-views', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/widget-views?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/widget-views", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/widget-views

Endpoint to retrieve widget views

Get widget views.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
widgetName query string false Widget Name to filter on.
widgetType query string false Widget type to filter on (advocateShare or emailCapture).
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 0,
  "results": [
    {
      "customerId": "ad39255f-b7e6-4c8b-baa8-5c7aa0c3e241",
      "email": "user@example.com",
      "widgetName": "Post Purchase Overlay",
      "campaignId": "st27d77a60-c446-4629-81a9-cc2eaa08738ering",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1",
      "widgetType": "advocateShare"
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [widgetViewsGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
customerId string false none Customer Id of the user who viewed the widget, if available.
email string(email) false none Email of the user who viewed the widget, if available.
widgetName string false none Name of the viewed widget.
campaignId string(uuid) false none Campaign Id associated with the viewed widget.
campaignName string false none Name of the campaign associated with the viewed widget.
createdOn string(date-time) false none Date and time the widget was viewed.
userAgent string false none User Agent of the user who viewed the widget.
ipAddress string(ipv4) false none IP Address of the user who viewed the widget.
widgetType string false none Type of the widget viewed. Either "advocateShare" or "emailCapture".

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. getWidgetViewsResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getShares

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/shares?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/shares?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/shares?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/shares',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/shares', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/shares', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/shares?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/shares", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/shares

Endpoint to retrieve shares

Get shares.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
advocateEmail query string(email) false Advocate email to filter on.
advocateCustomerId query string false Advocate customer id to filter on.
channel query string false Share channel to filter on.
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "advocateCustomerId": "c9a58f97-7d2c-4cfd-a8e7-ed404038d2b2",
      "advocateEmail": "user@example.com",
      "advocateName": "Test Advocate",
      "channel": "email",
      "referralCode": "abc123",
      "campaignId": "ad39255f-b7e6-4c8b-baa8-5c7aa0c3e241",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1"
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [sharesGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
advocateCustomerId string false none Customer Id of the advocate who shared.
advocateEmail string(email) false none Email of the advocate who shared.
advocateName string false none Name of the advocate who shared.
channel string false none The channel the user shared through (e.g. email, facebook, twitter, purl)
referralCode string false none The referral code of the share.
campaignId string(uuid) false none The id of the campaign the share originated from.
campaignName string false none The name of the campaign the share originated from.
createdOn string(date-time) false none The date the share was made.
userAgent string false none The user agent of the advocate who shared.
ipAddress string(ipv4) false none The ip address of the advocate who shared.

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. getSharesResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getClicks

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/clicks?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/clicks?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/clicks?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/clicks',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/clicks', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/clicks', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/clicks?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/clicks", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/clicks

Endpoint to retrieve valid clicks

Get valid clicks.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
channel query string false Filter for clicks that came from a specific channel.
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 0,
  "results": [
    {
      "advocateCustomerId": "e24b313b-c941-4baf-8762-34b3af8cddee",
      "advocateEmail": "user@example.com",
      "advocateName": "Test Advocate",
      "channel": "purl",
      "referralCode": "abc123",
      "campaignId": "1b9accd7-8ec5-4ff6-8d22-941fdc7338f4",
      "campaignName": "Holiday Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1",
      "destinationUrl": "https://example.com"
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [clicksGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
advocateCustomerId string false none Customer Id associated of the advocate who's link was clicked on.
advocateEmail string(email) false none Email of the advocate who's link was clicked on.
advocateName string false none Name of the advocate who's link was clicked on.
channel string false none The channel of the link that was clicked (e.g. email, facebook, etc.)
referralCode string false none The referral code of the link that was clicked.
campaignId string(uuid) false none The campaign id of the link that was clicked.
campaignName string false none The campaign name of the link that was clicked.
createdOn string(date-time) false none Timestamp of the click.
userAgent string false none User agent of the user who clicked the link.
ipAddress string(ipv4) false none Ip address of the user who clicked the link.
destinationUrl string false none The url the user was directed to after clicking the link.

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. getClicksResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getSignups

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/account-sign-ups?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/account-sign-ups?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/account-sign-ups?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/account-sign-ups',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/account-sign-ups', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/account-sign-ups', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/account-sign-ups?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/account-sign-ups", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/account-sign-ups

Endpoint to retrieve referral signups

Get referral signups.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
customerId query string false Customer id to filter on. This will filter based on the customer id of the user who signed up.
email query string(email) false Email to filter on. This will filter based on the email of the user who signed up.
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "customerId": "1b9accd7-8ec5-4ff6-8d22-941fdc7338f4",
      "email": "user@example.com",
      "name": "Test Friend",
      "campaignId": "03bbcf1f-c0d1-4868-af7c-3b65d44a410d",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36",
      "ipAddress": "192.168.0.1",
      "advocateName": "Test Advocate",
      "advocateEmail": "advocate@example.com",
      "advocateCustomerId": "61dbe3d5-8134-4a96-80e4-540f2df678b2",
      "newCustomer": true,
      "referralCode": "abc123"
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [signupsGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
customerId string false none The customer id of the user who signed up.
email string(email) false none Email of the user who signed up.
name string false none Name of the user who signed up.
campaignId string false none Id of the campaign that the user who signed up was referred through.
campaignName string false none Name of the campaign that the user who signed up was referred through.
createdOn string(date-time) false none Timestamp of the signup.
userAgent string false none User agent of the user who signed up.
ipAddress string(ipv4) false none IP address of the user who signed up.
advocateName string false none Name of the advocate who referred the user that signed up.
advocateEmail string(email) false none Email of the advocate who referred the user that signed up.
advocateCustomerId string false none Customer id of the advocate who referred the user that signed up.
newCustomer boolean false none Indicates whether or not the user who signed up was a new customer.
referralCode string false none The referral code of the link the user who signed up clicked on.
channel string false none The channel of the link the user who signed up clicked on (e.g. email, purl, facebook, etc.).

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. getSignupsResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getPurchases

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/purchases?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/purchases?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/purchases?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/purchases',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/purchases', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/purchases', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/purchases?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/purchases", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/purchases

Endpoint to retrieve referral purchases

Get referral purchases.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
customerId query string false Customer id to filter on. This will filter based on the customer id of the user who signed up.
email query string(email) false Email to filter on. This will filter based on the email of the user who signed up.
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "customerId": "fbdb5742-6fe4-40cb-95da-df8b02708627",
      "email": "user@example.com",
      "name": "Test Customer",
      "campaignId": "abc52d7f-828d-44e4-8b0d-79df62fdae9c",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "ipAddress": "192.168.0.1",
      "advocateName": "Test Advocate",
      "advocateEmail": "advocate@example.com",
      "advocateCustomerId": "da6c99b7-4040-4677-a152-ef7bebc13b99",
      "newCustomer": true,
      "referralCode": "abc123",
      "amount": 50.0,
      "couponCode": "test-coupon-1",
      "products": [
        {
          "sku": "test-product-1",
          "name": "Test Product",
          "quantity": 2,
          "price": 25.0
        }
      ]
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [purchasesGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
customerId string false none Customer id of the user who made the purchase.
email string(email) false none Email of the user who made the purchase.
name string false none Name of the user who made the purchase.
campaignId string false none Id of the campaign the user who made the purchase was referred from.
campaignName string false none Name of the campaign the user who made the purchase was referred from.
createdOn string(date-time) false none Timestamp of the purchase.
ipAddress string(ipv4) false none IP address of the user who made the purchase.
advocateName string false none Name of the advocate who referred the user who made a purchase.
advocateEmail string(email) false none Email of the advocate who referred the user who made a purchase.
advocateCustomerId string false none Customer id of the advocate who referred the user who made a purchase.
newCustomer boolean false none Indicates whether or not the user who made the purchase is a new customer.
referralCode string false none The referral code of the link the user who made the purchase clicked on.
amount number false none Total amount of the purchase.
couponCode string false none Any coupon code used on the purchase.
products [product] false none Any products contained in the purchase.

Product Response

Name Type Required Restrictions Description
sku string true none SKU of the product.
name string false none Name of the product.
quantity integer false none Number of products purchased.
price integer false none Price of the product.

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. getPurchasesResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getDistributedAdvocateRewards

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/distributed-advocate-rewards", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/distributed-advocate-rewards

Endpoint to retrieve distributed advocate rewards

Get distributed advocate rewards.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
advocateCustomerId query string false Customer id to filter on. This will filter based on the customer id of the advocate who received the reward.
advocateEmail query string(email) false Email to filter on. This will filter based on the email of the advocate who received the reward.
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "createdOn": "2021-02-23T23:18:59Z",
      "rewardType": "Coupon Code",
      "rewardAmount": 10.0,
      "couponCode": "test-coupon-1",
      "trigger": "purchase",
      "advocateEmail": "advocate@example.com",
      "advocateName": "Test Advocate",
      "advocateCustomerId": "4fe0f0cc-14c6-44c3-ba51-dda17412199a",
      "referralCode": "abc123",
      "channel": "facebook",
      "friendEmail": "friend@example.com",
      "friendName": "Test Friend",
      "friendCustomerId": "2a3e06d4-4e99-47c6-b57f-8cb6b86f77ab",
      "campaignId": "5727868f-1a1f-4b26-8104-b8a93b0c30db",
      "campaignName": "Holiday Campaign"
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [distributedAdvocateRewardsGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
createdOn string false none Timestamp indicating when the reward was created.
rewardType string false none One of "Account Credit", "Coupon Code", "Gift Card", "Custom", or "Ledger"
rewardAmount number false none The monetary value of the reward.
couponCode string false none The coupon code issued with the reward, if any.
trigger string false none The event that triggered the reward.
advocateEmail string false none The email of the advocate who received the reward.
advocateName string false none The name of the advocate who received the reward.
advocateCustomerId string false none The customer id of the advocate who received the reward.
referralCode string false none The referral code associated with the reward. This code belongs to the share the referred friend clicked on before converting.
channel string false none The share channel the referred friend clicked on before converting.
friendEmail string false none The email of the referred friend.
friendName string false none The name of the referred friend.
friendCustomerId string false none The customer id of the referred friend.
campaignId string false none The id of the campaign the reward was issued from.
campaignName string false none The name of the campaign the reward was issued from.

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. distributedRewardsGetResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getDistributedFriendIncentives

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/distributed-friend-incentives?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/distributed-friend-incentives?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/distributed-friend-incentives?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/distributed-friend-incentives',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/distributed-friend-incentives', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/distributed-friend-incentives', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/distributed-friend-incentives?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/distributed-friend-incentives", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/distributed-friend-incentives

Endpoint to retrieve distributed friend incentives

Get distributed friend incentives.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
friendCustomerId query string false Customer Id to filter on. This will filter based on the customer id of the user who received the incentive.
friendEmail query string(email) false Email to filter on. This will filter based on the email of the user who received the incentive.
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "createdOn": "2019-11-05T01:07:38.509Z",
      "rewardType": "Coupon Code",
      "rewardAmount": 5.0,
      "couponCode": "test-coupon-2",
      "trigger": "email_capture",
      "advocateEmail": "advocate@example.com",
      "advocateName": "Test Advocate",
      "advocateCustomerId": "0655e7df-a925-4e56-8509-5c1cbdb78bc2",
      "referralCode": "abc123",
      "channel": "messenger",
      "friendEmail": "friend@example.com",
      "friendName": "Test Friend",
      "friendCustomerId": "ea31b0f9-6af8-4c05-835f-c60cd18f0c50",
      "campaignId": "8c3153f2-2692-4e42-8f95-72eacd36860b",
      "campaignName": "Test Campaign"
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [distributedFriendIncentivesGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
createdOn string false none Timestamp indicating when the incentive was created.
incentiveType string false none One of "Account Credit", "Coupon Code", "Gift Card", "Custom", or "Ledger"
incentiveAmount number false none The monetary value of the incentive.
couponCode string false none The coupon code issued with the incentive, if any.
trigger string false none The event that triggered the incentive.
advocateEmail string false none The email of the advocate who referred their friend.
advocateName string false none The name of the advocate who referred their friend.
advocateCustomerId string false none The customer id of the advocate who referred their friend.
referralCode string false none The referral code associated with the incentive. This code belongs to the share the referred friend clicked on before converting.
channel string false none The share channel the referred friend clicked on before converting.
friendEmail string false none The email of the referred friend who received the incentive.
friendName string false none The name of the referred friend who received the incentive.
friendCustomerId string false none The customer id of the referred friend who received the incentive.
campaignId string false none The id of the campaign the incentive was issued from.
campaignName string false none The name of the campaign the incentive was issued from.

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. distributedRewardsGetResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getEmailCaptures

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/email-captures?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/email-captures?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/email-captures?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/email-captures',
  params: {
  'fromDate' => 'string(date-time)',
'toDate' => 'string(date-time)'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/email-captures', params={
  'fromDate': '2020-01-05T01:07:38.509Z',  'toDate': '2021-01-05T01:07:38.509Z'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/email-captures', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/email-captures?fromDate=2020-01-05T01%3A07%3A38.509Z&toDate=2021-01-05T01%3A07%3A38.509Z");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/email-captures", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/email-captures

Endpoint to retrieve email captures

Get email captures.

Parameters

Name In Type Required Description
fromDate query string(date-time) true Beginning of the search period.
toDate query string(date-time) true End of the search period.
campaignId query string(uuid) false Campaign Id to filter on.
emailCaptureType query string false The type of email capture to filter on. One of "advocate" or "friend".
email query string(email) false Email to filter on. This will filter based on the email captured.
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.
pageSize query string false Page size limit.

Enumerated Values

Parameter Value
emailCaptureType advocate
emailCaptureType friend

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1,
  "results": [
    {
      "name": "Test Customer",
      "email": "user@example.com",
      "widgetName": "Friend Incentive Widget",
      "campaignId": "de07e043-0730-4d32-b52c-146ba61cb859",
      "campaignName": "Evergreen Campaign",
      "createdOn": "2021-02-23T01:20:14Z",
      "ipAddress": "192.168.0.1",
      "emailCaptureType": "friend",
      "newsletterOptIn": true
    }
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [emailCapturesGetResponse_results] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
name string false none Name submitted with the email capture, if any.
email string(email) false none The captured email.
widgetName string false none The name of the widget used to capture the email.
campaignId string(uuid) false none The id of the campaign used to capture the email.
campaignName string false none The name of the campaign used to capture the email.
createdOn string(date-time) false none Timestamp of the email capture.
ipAddress string(ipv4) false none IP address of the user who submitted their email.
emailCaptureType string false none The type of email capture based on the widget the email was submitted to. One of "advocate", "friend", or "other". "Other" means the email was captured by a friend incentive widget, but did not have any attribution associated with it.
newsletterOptIn boolean false none Whether or not the user opted in to receive newsletters.

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. getEmailCapturesResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getEmailMetrics

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/email-metrics?fromDate=2021-04-07&toDate=2021-04-07&zone=America%2FLos_Angeles&includeSeries=true \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/email-metrics?fromDate=2021-04-07&toDate=2021-04-07&zone=America%2FLos_Angeles&includeSeries=true HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch(
  "https://mapi.fbot.me/v1/analytics/email-metrics?fromDate=2021-04-07&toDate=2021-04-07&zone=America%2FLos_Angeles&includeSeries=true",
  {
    method: "GET",

    headers: headers,
  }
)
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/email-metrics',
  params: {
  'fromDate' => 'string(date)',
'toDate' => 'string(date)',
'zone' => 'string',
'includeSeries' => 'true',
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/email-metrics', params={
  'fromDate': '2021-04-07',  'toDate': '2021-04-07',  'zone': 'America/Los_Angeles',
  'includeSeries': 'true',
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/email-metrics', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/email-metrics?fromDate=2021-04-07&toDate=2021-04-07&zone=America%2FLos_Angeles&includeSeries=true");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/email-metrics", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/email-metrics

Endpoint to retrieve email metrics

Get email metrics.

Parameters

Name In Type Required Description
fromDate query string(date) true Beginning of the search period. Whole dates only (no timestamps).
toDate query string(date) true End of the search period. Whole dates only (no timestamps).
zone query string true Timezone for the search period.
campaignId query string(uuid) false Campaign Id to filter results on.
widgetId query string(uuid) false Widget Id to filter results on.
includeSeries query string false Indicates whether or not to include a timeseries in the results. Defaults to false.

Example responses

200 Response

{
  "fromDate": "2021-04-07",
  "toDate": "2021-04-07",
  "zone": "string",
  "shareEmails": {
    "totalOpens": 10,
    "uniqueOpens": 7,
    "uniqueClicks": 13,
    "totalClicks": 15,
    "shares": 14,
    "recipients": 17,
    "delivered": 14,
    "bounced": 0,
    "spam": 0
  },
  "reminderEmails": {
    "totalOpens": 5,
    "uniqueOpens": 2,
    "uniqueClicks": 5,
    "totalClicks": 7,
    "shares": 4,
    "recipients": 4,
    "delivered": 4,
    "bounced": 0,
    "spam": 0
  },
  "series": [
    {
      "date": "2021-04-07",
      "shareEmails": {
        "totalOpens": 10,
        "uniqueOpens": 7,
        "uniqueClicks": 13,
        "totalClicks": 15,
        "shares": 14,
        "recipients": 17,
        "delivered": 14,
        "bounced": 0,
        "spam": 0
      },
      "reminderEmails": {
        "totalOpens": 5,
        "uniqueOpens": 2,
        "uniqueClicks": 5,
        "totalClicks": 7,
        "shares": 4,
        "recipients": 4,
        "delivered": 4,
        "bounced": 0,
        "spam": 0
      }
    }
  ]
}

Responses

Name Type Required Restrictions Description
fromDate string(date) false none Beginning of the search period.
toDate string(date) false none End of the search period.
zone string false none Timezone for the search period.
shareEmails ShareEmailMetricsSeriesItem false none Metrics for initial share emails.
reminderEmails ReminderEmailMetricsSeriesItem false none Metrics for reminder emails.
series [EmailMetricsSeries] false none A time series that breaks down metrics by day. Only include if includeSeries is true.

EmailMetricsSeries

Name Type Required Restrictions Description
date string false none Date for the series item
shareEmails ShareEmailMetricsSeriesItem false none Share email metrics for the specified date.
reminderEmails ReminderEmailMetricsSeriesItem false none Reminder email metrics for the specified date.

ShareEmailMetricsSeriesItem

Name Type Required Restrictions Description
totalOpens number false none Total number of email open events.
uniqueOpens number false none Number of unique emails opened.
uniqueClicks number false none Number of unique emails clicked.
totalClicks number false none Total number of email click events.
shares number false none Total number of email shares.
recipients number false none Number of recipients for email shares (can be greater than the number of shares).
delivered number false none Number of emails delivered.
bounced number false none Number of emails bounced.
spam number false none Number of emails that received spam complaints.

ReminderEmailMetricsSeriesItem

Name Type Required Restrictions Description
totalOpens number false none Total number of email open events.
uniqueOpens number false none Number of unique emails opened.
uniqueClicks number false none Number of unique emails clicked.
totalClicks number false none Total number of email click events.
recipients number false none Number of recipients for email shares (can be greater than the number of shares).
delivered number false none Number of emails delivered.
bounced number false none Number of emails bounced.
spam number false none Number of emails that received spam complaints.

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. emailMetricsGetResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

getLedgerHeads

Code samples

# You can also use wget
curl -X GET https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads?currency=USD \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

GET https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads?currency=USD HTTP/1.1
Host: mapi.fbot.me
Accept: application/json

const headers = {
  Accept: "application/json",
  Authorization: "Bearer {access-token}",
};

fetch("https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads?currency=USD", {
  method: "GET",

  headers: headers,
})
  .then(function (res) {
    return res.json();
  })
  .then(function (body) {
    console.log(body);
  });
require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.get 'https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads',
  params: {
  'currency' => 'string'
}, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.get('https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads', params={
  'currency': 'USD'
}, headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads?currency=USD");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "https://mapi.fbot.me/v1/analytics/loyalty/ledger-heads", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /v1/analytics/loyalty/ledger-heads

Endpoint to retrieve the ledger heads for all customers for a given currency

Get loyalty ledger heads by currency.

Parameters

Name In Type Required Description
currency query string true The ledger currency to filter on. This can be a normal currency like USD or CAD or a custom points currency defined in your account.
pageSize query string false Will be ignored if pageToken is present
pageToken query string false The page token used to specify which page of results to use. Will be provided in the response to previous requests.

Example responses

200 Response

{
  "nextPageToken": "eyJzZWFyY2hBZnRlciI6WzE1OTY1NzE5NDM0NDksIjI1YmU3NDhkLWEyYTgtNDA5ZS1iMmU3LTUyNGU2NGFhY2YzYzg0Y2EyMmJmLTZjZDgtNDQxMy1iOTM0LTM3ZDE1NDhhMGU0NCJdLCJmcm9tRGF0ZSI6IjIwMTktMTItMzFUMDg6MDA6MDAuMDAwWiIsInRvRGF0ZSI6IjIwMjEtMDEtMDFUMDc6NTk6NTkuOTk5WiIsInBhZ2VTaXplIjoyMDAsInpvbmUiOiJBbWVyaWNhL0xvc19BbmdlbGVzIn0",
  "totalResults": 1024,
  "results": [
    {
      "customerId": "de07e043-0730-4d32-b52c-146ba61cb859",
      "currency": "USD",
      "currentBalance": 100,
      "lastUpdatedOn": "2021-12-02T00:41:48Z"
    },
    ...
  ]
}

Responses

Name Type Required Restrictions Description
nextPageToken string false none A token representing the next page of results. Pass this token in as pageToken with your next request.
totalResults number false none The total number of results.
results [GetLedgerHeadsResult] false none The records retrieved for this page.

Results

Name Type Required Restrictions Description
customerId string false none none
currency string false none none
currentBalance number false none none
lastUpdatedOn string(date-time) false none none

Response Codes

Status Meaning Description Schema
200 OK 0 or more records are retrieved. getLedgerHeadsResponse
422 Unprocessable Entity Unprocessable Entity Error
429 Too Many Requests Too many requests Error
500 Internal Server Error Internal Server Error (uncontrolled failure) Error

Errors

Name Type Required Restrictions Description
error string false none The error name.
message string false none The error details.
code number false none The status code of the error.
reference string false none A reference string that can be sent to friendbuy for debugging.

Timezones

All world timezones are supported.

"America/Adak"

Enumerated Values

Example Values
America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina
America/Aruba
America/Asuncion
America/Atikokan
America/Atka
America/Bahia
America/Bahia_Banderas
America/Barbados
America/Belem
America/Belize
America/Blanc
America/Boa_Vista
America/Bogota
America/Boise
America/Buenos_Aires
America/Cambridge_Bay
America/Campo_Grande
America/Cancun
America/Caracas
America/Catamarca
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Coral_Harbour
America/Cordoba
America/Costa_Rica
America/Creston
America/Cuiaba
America/Curacao
America/Danmarkshavn
America/Dawson
America/Dawson_Creek
America/Denver
America/Detroit
America/Dominica
America/Edmonton
America/Eirunepe
America/El_Salvador
America/Ensenada
America/Fortaleza
America/Fort_Nelson
America/Fort_Wayne
America/Glace_Bay
America/Godthab
America/Goose_Bay
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Hermosillo
America/Indiana
America/Indianapolis
America/Inuvik
America/Iqaluit
America/Jamaica
America/Jujuy
America/Juneau
America/Kentucky
America/Knox_IN
America/Kralendijk
America/La_Paz
America/Lima
America/Los_Angeles
America/Louisville
America/Lower_Princes
America/Maceio
America/Managua
America/Manaus
America/Marigot
America/Martinique
America/Matamoros
America/Mazatlan
America/Mendoza
America/Menominee
America/Merida
America/Metlakatla
America/Mexico_City
America/Miquelon
America/Moncton
America/Monterrey
America/Montevideo
America/Montreal
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
America/North_Dakota
America/Ojinaga
America/Panama
America/Pangnirtung
America/Paramaribo
America/Phoenix
America/Port
America/Porto_Acre
America/Porto_Velho
America/Port_of_Spain
America/Puerto_Rico
America/Punta_Arenas
America/Rainy_River
America/Rankin_Inlet
America/Recife
America/Regina
America/Resolute
America/Rio_Branco
America/Rosario
America/Santarem
America/Santa_Isabel
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/Scoresbysund
America/Shiprock
America/Sitka
America/St_Barthelemy
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Swift_Current
America/Tegucigalpa
America/Thule
America/Thunder_Bay
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Virgin
America/Whitehorse
America/Winnipeg
America/Yakutat
America/Yellowknife