Segments API

About Segments

Segments are used for both Program & Rules logic and reporting. Functional examples of Segments are:

  1. Create a segment of "Power Users," and restrict cash bonuses to these users only

  2. Create a segment of "Churned Users" to report on high-risk users as soon as possible

Most Segments will be maintained programmatically using Program & Rule logic. However the Segments API allows you to directly add or remove users from a segment through an API request.

Functional use cases for using the Segments API instead of Program & Rules logic:

  1. You want to assign users to a geographical region as soon as they sign up (Example: "User from Miami" based on GPS location data at signup)

  2. You want to override Rules logic for a consistent use case (Example: "Developer Test Account")

To see more about real-world Segment use cases, check out our Guides->.

Creating & Viewing Segments on the Admin Dash

You must create a Segment on the Admin Dashboard before it will be accepted via the Segments API.

If an Activity is sent through the Activity API without having been defined on the Admin Dashboard, it be rejected. Any Network Admin can create or edit segments.

To create a Segment, navigate to Side Menu -> Incentives -> Segments -> New Segment. For more information visit Segments ->.

Endpoint

POST/networks/YOUR_NETWORK_ID/segments

Where 'YOUR_NETWORK_ID' is replaced with your actual Network ID.

API Field Overview

Warning: Adding a user to a Segment via the Segments API will override any automated Program & Rule logic that manages segments.

The Segments API allows you to take the following actions:

  1. Add a user to a Segment. This adds the user to a segment and overrides any existing Program & Rule logic that might remove them in the future.

  2. Block a user from a Segment. This removes a user from the segment if they were already a member, and blocks them from being added via Program & Rule logic in the future.

  3. Reset a user's existing Add or Block overrides. This does not change Segment status but it allows Program and Rule logic to affect this user's Segment membership going forward.

Body Fields

Field NameJSON KeyTypeDescriptionRequired

User

user

string

The user. May be email or user_id.

Yes

Segment ID

segment_id

integer

The unique segment ID associated with this segment. It is created automatically when a new segment is created, and is viewable on the Village Admin Dashboard.

Yes

User Status

user_status

string

Options include: 1. "add" -> Adds the user to the segment. Adding a user via Segments API overrides automation logic. 2. "block" -> Blocks the user from being a member. Overrides automation logic. 3. "reset" -> Removes automation override from previous Add or Block overrides.

Yes

Metadata

metadata

object

Additional metadata for the user status change. See Metadata fields for options.

No

Metadata

Field NameJSON KeyTypeDescriptionRequired

Reference ID

reference_id

string

An optional identifier that can be used for reporting purposes.

No

Status Change Timestamp

status_change_timestamp

integer

The Unix timestamp of when the segment status change occurred. If this is blank, Village will use the timestamp the data was received via the Village API as the Status Change Timestamp.

No

Description

description

string

A reason and description for the segment status change.

No

Examples

Body

// Example Segments Body
{
    "user": "johnny.invite@villagelabs.co",
    "segment_id": 1,
    "user_status": "add",
    "metadata": {
        "reference_id": "dpi_Ylo2Cfr8US8u1JIdAl2eZvKB",
        "status_change_timestamp": 1664900628,
        "description": "New user signup"
    }
}

By Language

//Remember to replace 'Bearer YOUR_API_KEY' and 'YOUR_NETWORK_ID' with your actual API key and Network ID

//SEGMENTS *********** 

// Function to submit activity data to API
function submitSegmentData() {
  // Get the active spreadsheet and specific sheets within it
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const settingsSheet = ss.getSheetByName("Settings");
  const segmentsSheet = ss.getSheetByName("Segments");

  // Get values from the "Settings" sheet
  const apiKey = settingsSheet.getRange("B2").getValue();
  const networkId = settingsSheet.getRange("B3").getValue();
  const endpointUrl = settingsSheet.getRange("B4").getValue();
  const path = settingsSheet.getRange("B6").getValue();
  
  // Construct the API endpoint URL
  const apiEndpoint = `${endpointUrl}/networks/${networkId}/${path}`;

  // Get data from the "Segments" sheet
  const segmentsData = segmentsSheet.getDataRange().getValues();

  // Loop over each row in segmentsData, starting from the second row
  for(let i = 1; i < segmentsData.length; i++) {
    let row = segmentsData[i];
    
    // Skip row if previously submitted successfully
    if(row[0] === 'Success') continue;

    // Prepare data object for API request
    let postData = {
      "user": row[2],
      "segment_id": parseInt(row[3]),
      "user_status": row[4]
    };

    // Log the postData to check the format
    Logger.log(`Row ${i + 1}: ${JSON.stringify(postData)}`);

    // Set options for API request
    let options = {
      "method": "POST",
      "headers": {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      "payload": JSON.stringify(postData),
      "muteHttpExceptions": true  // Prevent exceptions from halting the execution
    };

    // Make the API call and handle response
    try {
      let response = UrlFetchApp.fetch(apiEndpoint, options);
      let responseCode = response.getResponseCode();
      let responseContent = JSON.parse(response.getContentText());

      // Log the response content
      Logger.log(`Response from row ${i + 1}: ${JSON.stringify(responseContent)}`);

      if(responseCode >= 200 && responseCode < 300) {
        segmentsSheet.getRange(i + 1, 1, 1, 2).setValues([["Success", responseCode]]);
      } else {
        let errorMessage = responseContent.error || "Unknown error";
        segmentsSheet.getRange(i + 1, 1, 1, 2).setValues([[`Failure: ${errorMessage}`, responseCode]]);
      }
    } catch (e) {
      segmentsSheet.getRange(i + 1, 1, 1, 2).setValues([[`Failure: ${e.message}`, ""]]);
    }
  }
}


Last updated