NAV Navbar
Logo
shell html javascript

Authentication

Authentication is done on an api key basis and should be included in the OSDI-API-Token header. To access the latest version the Accept header must be supplied with application/vnd.sync.v2+json+hal to access the latest version of the API.

You can get your api key per user with your instance of Sync.

HTTP Request

POST https://sync.revmsg.net/api/authenticate

curl -X POST \
     "https://sync.revmsg.net/api/authenticate" \
  -H 'accept: application/vnd.sync.v2+json' \
  -H 'cache-control: no-cache' \
  -H 'osdi-api-token: b7de668f-3ecd-40cf-bb11-7427041d15f8' \
var request = require("request");

var options = { method: "POST",
  url: "http://localhost:3000/api/authenticate",
  headers: 
   { "cache-control": "no-cache",
     "osdi-api-token": "b7de668f-3ecd-40cf-bb11-7427041d15f8",
     "accept": "application/vnd.sync.v2+json" } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

This will return a token in which you can place into the Authorization header with Bearer <token> as the value. This token will expire in 24 hours and that time is also listed on the response.

The above returns JSON response of:

{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJoZCI6AjU5MLI1ODPxMjZjZmQ1YWEyZWExYzU4NSIsImlhdCI6MTQ5MzMyNTg2MSwidG9rZW5fdHlwZSI6ImFwaSIsImV4cCI6MTQ5MzQxMjI2MSwidXNlcm5hbWUiOiJzso9iZXJ0c29uQHJldm9sdXRpb25tZXNzYWdpbmcuY29tIiwidXNlcl90eXBlIjoiUmV2QWRtaW4ifQ.3-dDu99OxIOdjI954JeSTMRvogG4WDk6dd1MnVvzjes",
  "auth_instructions": "Place this token into Authorization: Bearer <token> to use the rest of the endpoints.",
  "expires": 1493412261557
}

Errors

Sync uses the following error codes:

Error Code Meaning
400 Bad Request – Invalid Request Params
401 Unauthorized – Your API key is wrong or deactivated.
404 Not Found – Data or Route not found.
500 Internal Server Error – We had a problem with our server. Try again later.
503 Service Unavailable – We’re temporarily offline for maintenance. Please try again later.

Entry Point

This unauthenticated route is to be used to discover the OSDI Sync API. It will return the possible resources to use with sync.

curl -X GET \
     "https://sync.revmsg.net/api" \
  -H 'accept: application/vnd.sync.v2+json' \

The above returns JSON response of:

{
  "_links": {
    "self": {
      "href": "/v2/api/"
    },
    "curies": [
      {
        "name": "revere_sync",
        "href": "/rels/Revolution Messaging/{rel}",
        "templated": true
      }
    ],
    "revere_sync:people": [
      {
        "href": "/v2/api/people"
      },
      {
        "href": "/v2/api/people/{id}",
        "templated": true
      },
      {
        "href": "/v2/api/people"
      }
    ]
  }
}

People

People are the main resource in the Revere Sync. This is the main entry point for Sync and where information is passed and retrivied.

Person Signup Helper

This route is desiged to create or update a person. The match is based on four paramaters, given_name, family_name, an email_address and a phone_number. If a person is found based on any of this information sync will return with updated person, otherwise the person will be created. The postal_addresses field and profiles fields will create additions. This means when new information is provided it is saved so be careful when creating postal_address fields and profiles. The email_addresses and phone_numbers fields will match on address for email_address and number for phone_numbers. Those will then update the details in respect to resource.

Triggers

Currently we support an auto respoonse using a mobile_flow_id. When provided this trigger will subscribe the primary_phone_number to a mobile list.

HTTP Request

POST https://sync.revmsg.net/api/people/person_signup_helper

curl -X POST \
  https://sync.revmsg.net/api/people/person_signup_helper \
  -H 'Accept: application/vnd.sync.v2+hal+json' \
  -H 'Authorization: Bearer <token>' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
  "person":{
    "given_name":"John",
    "family_name":"Doe",
    "identifiers": [
        "vanId:252"
    ],
    "party_identification":"Democratic",
    "custom_fields":{
      "some_string":"here",
      "boolean_value":false,
      "number_value":15
    },
    "birthdate":{
        "year": 1992,
        "month": 11,
        "day": 25
    },
    "postal_addresses":[
      {
        "primary":true,
        "locality":"Seattle",
        "region":"WA",
        "addressLine1":"515 Example St.",
        "postal_code":"98036",
        "address_type":"Home"

      }
    ],
    "phone_numbers":[
        {
          "number":"+1234567890",
          "number_type":"Mobile",
          "primary":true
        }
      ],
    "email_addresses":[
        {
          "address":"john@doe.com",
          "address_type":"Work",
          "primary":true
        }
      ],
    "profiles":[
      {
        "url":"https://twitter.com/johndoe15",
        "handle":"johndoe15",
        "profile_provider":"twitter"
      }
    ],
    "triggers":{
      "autoresponse":{
        "enabled":true,
        "revere_mobile_flow_trigger":{
          "params":{
            "mobile_flow_id":"58c1vcfae4b0569e60c923fd"
          }
        }
      }
    }  
  }
}'
var request = require("request");

var options = { method: "POST",
  url: "https://sync.revmsg.net/api/people/person_signup_helper",
  headers: 
   { "cache-control": "no-cache",
     "content-type": "application/json",
     "accept": "application/vnd.sync.v2+hal+json",
     "authorization": "Bearer <token>" },
  body: 
   {
    person: {
      given_name:"John",
      family_name:"Doe",
      identifiers: [
          "vanI:252"
      ],
      party_identification:"Democratic",
      custom_fields:{
          some_string:"here",
          boolean_value:false,
          number_value:15
      },
      birthdate:{
        year: 1992,
        month: 11,
        day: 25
      },
      postal_addresses:[
          {
              primary:true,
              locality:"Seattle",
              region:"WA",
              addressLine1:"515 Example St.",
              postal_code:"98036",
              address_type:"Home"

          }
      ],
      phone_numbers:[
              {
                  number:"+1234567890",
                  number_type:"Mobile",
                  primary:true
              }
          ],
      email_addresses:[
              {
                  address:"john@doe.com",
                  address_type:"Work",
                  primary:true
              }
          ],

      profiles:[
          {
              url:"http://twitter.com/johndoe15",
              handle:"johndoe15",
              profile_provider:"twitter"
          }
      ],
      triggers: {
        autoresponse: {
          enabled: true,
          revere_mobile_flow_trigger: {
            params: {
              mobile_flow_id:"58c1vcfae4b0569e60c923fd"
            }
          }
        }
      }
    } 
   },
  json: true
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});


The above returns JSON response of on create or update:

{
  "_links": {
    "self": [
      {
        "href": "/v2/api/people"
      },
      {
        "href": "http://sync.revmsg.net/api/people/ae87ccde-7d82-4554-bded-56f305a4d323"
      }
    ]
  },
  "revere_sync_id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "identifiers": [
    "vanId:252",
    "revere_sync:ae87ccde-7d82-4554-bded-56f305a4d323"
  ],
  "id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "family_name": "Doe",
  "given_name": "John",
  "additional_name": null,
  "honorific_prefix": null,
  "origin_system": "revere_sync",
  "party_identification": "Democratic",
  "preferred_language": "en",
  "source": null,
  "birthdate": {
    "year": 1999,
    "month": 11,
    "day": 22
  },
  "employer": null,
  "gender": null,
  "custom_fields": {
    "some_string": "here",
    "boolean_value": false,
    "number_value": 15
  },
  "ngp_van_sync_status": null,
  "mobile_sync_status": null,
  "created_at": "2017-05-23T09:30:49.569Z",
  "updated_at": "2017-05-23T09:30:49.569Z",
  "email_addresses": [
    {
      "address_type": "Work",
      "status": null,
      "primary": true,
      "address": "john@doe.com",
      "email_address_type": "work",
      "email_subscription_status": null,
      "updated_at": "2017-05-23T09:30:49.602Z"
    }
  ],
  "phone_numbers": [
    {
      "number_type": "Mobile",
      "primary": true,
      "number": "+1234567890",
      "description": null,
      "operator": null,
      "country": null,
      "sms_capable": false,
      "do_not_call": false,
      "phone_number_type": "mobile",
      "updated_at": "2017-05-23T09:30:49.604Z"
    }
  ],
  "postal_addresses": [
    {
      "location": {
        "latitude": null,
        "longitude": null,
        "accuracy": null
      },
      "address_type": "Home",
      "status": "Potential",
      "primary": true,
      "venue": null,
      "addressLine1": "515 Example St.",
      "addressLine2": null,
      "addressLine3": null,
      "locality": "Seattle",
      "region": "WA",
      "postal_code": 98036,
      "postal_code_plus_4": null,
      "country": "US",
      "language": "en",
      "latitude": null,
      "longitude": null,
      "accuracy": null,
      "last_verified_date": null,
      "postal_address_type": "home",
      "postal_address_status": "potential",
      "updated_at": "2017-05-23T09:30:49.604Z"
    }
  ]
}

Post Parameters

Properties Type Required Description
given_name string true First Name or Given Name of a Person.
family_name string true Family or Last Name of a Person.
identifiers array false External ID, can provide a list
party_identification string false Democratic, Republican, Independent, Other.
custom_fields object false Object of custom fields IE: { foo:bar }
birthdate object false Object of OSDI birthday IE: { year: 2000, month:1, day:1 }
email_addresses array true Array of at least one primary Email object.
phone_numbers array true Array of at least one Phone Number object.
postal_addresses array false Array of at least one Phone Number object.
profiles array false Array of profile objects.
triggers object false Object with autoresponse triggers with params.

Note: primary:true should be the first item in the list of email_addresses, phone_numbers, postal_addresses.

Email Address

Properties Type Required Description
address_type string false Can be “Personal”, “Work”, “Other”.
status string false Can be “Subscribed”, “Unsubscribed”.
primary boolean false Can be true or false if primary email address.
address string true A valid email address.

Phone Number

Properties Type Required Description
number_type string false Can be “Home”, “Work”, “Mobile”, “Other”, “Daytime”, “Evening”, “Fax”.
primary boolean false Can be true or false if primary phone number.
number string true E.164 formatted US phone number.
description string false Number description, max length is 50 chars.
operator string false Network Carrier.
sms_capable boolean false True if the number is able to receive sms and mms messages.
do_not_call boolean false If number should not be called.
country string false The country code according to ISO 3166-1 Alpha-2.

Postal Addresses

Properties Type Required Description
primary boolean false True if this is as a primary address, can only have one primary address
address_type string false The type of address. One of “Home”, “Work”, or “Mailing”.
venue string false Optional venue name at the address, useful for names of buildings. ex: Smith Hall)
addressLine1 string false Primary Address Line
addressLine2 string false Secondary Address Line
addressLine3 string false Final Address Line
locality string false A city or other local administrative area.
region string false State or subdivision codes according to ISO 3166-2 Final 2 alpha digits).
postal_code string false Five or Nine digit US postal code.
country string false The country code according to ISO 3166-1 Alpha-2.
language string false Language in which the address is recorded – language code according to ISO 639.
location object false { latitude: number, longitude: number, accuracy:"Rooftop" or "Approximate" }
status string false The type of address. One of “Home”, “Work”, or “Mailing”.
last_verified_date date false Date last verified of the address.

Profiles

Properties Type Required Description
url string false Social Profile URL
provider string false Social Profile Provider “Facebook”, “Twitter”, “Other”
id string false External Profile id
handle string false Social Profile Media Handle

Find Or Create a Person

This route is desiged to create or match a person. The match is based on four paramaters, given_name, family_name, an email_address and a phone_number. If a person is found based on any of this information sync will return with the full id of the person, otherwise the person will be created.

A person will be returned with standard OSDI fields but will also contain extra due to the naming scheme of our internal systems. Both can be used but OSDI 1.1 fields are recomended.

HTTP Request

POST https://sync.revmsg.net/api/people

curl -X POST \
  https://sync.revmsg.net/api/people \
  -H 'Accept: application/vnd.sync.v2+hal+json' \
  -H 'Authorization: Bearer <token>' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
    "given_name":"John",
    "family_name":"Doe",
    "identifiers": [
        "vanId:252"
    ],
    "party_identification":"Democratic",
    "custom_fields":{
        "some_string":"here",
        "boolean_value":false,
        "number_value":15
    },
    "birthdate":{
      "year": 1992,
      "month": 11,
      "day": 25
    },
    "postal_addresses":[
        {
            "primary":true,
            "locality":"Seattle",
            "region":"WA",
            "addressLine1":"515 Example St.",
            "postal_code":"98036",
            "address_type":"Home"

        }
    ],
    "phone_numbers":[
            {
                "number":"+1234567890",
                "number_type":"Mobile",
                "primary":true
            }
        ],
    "email_addresses":[
            {
                "address":"john@doe.com",
                "address_type":"Work",
                "primary":true
            }
        ],

    "profiles":[
        {
            "url":"https://twitter.com/johndoe15",
            "handle":"johndoe15",
            "profile_provider":"twitter"
        }
    ]
}'
var request = require("request");

var options = { method: "POST",
  url: "https://sync.revmsg.net/api/people",
  headers: 
   { "cache-control": "no-cache",
     "content-type": "application/json",
     "accept": "application/vnd.sync.v2+hal+json",
     "authorization": "Bearer <token>" },
  body: 
   {
    given_name:"John",
    family_name:"Doe",
    identifiers: [
        "vanI:252"
    ],
    party_identification:"Democratic",
    custom_fields:{
        some_string:"here",
        boolean_value:false,
        number_value:15
    },
    birthdate:{
      year: 1992,
      month: 11,
      day: 25
    },
    postal_addresses:[
        {
            primary:true,
            locality:"Seattle",
            region:"WA",
            addressLine1:"515 Example St.",
            postal_code:"98036",
            address_type:"Home"

        }
    ],
    phone_numbers:[
            {
                number:"+1234567890",
                number_type:"Mobile",
                primary:true
            }
        ],
    email_addresses:[
            {
                address:"john@doe.com",
                address_type:"Work",
                primary:true
            }
        ],

    profiles:[
        {
            url:"http://twitter.com/johndoe15",
            handle:"johndoe15",
            profile_provider:"twitter"
        }
    ]
   },
  json: true
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

The above returns JSON response of on create:

{
  "_links": {
    "self": [
      {
        "href": "/v2/api/people"
      },
      {
        "href": "http://sync.revmsg.net/api/people/ae87ccde-7d82-4554-bded-56f305a4d323"
      }
    ]
  },
  "revere_sync_id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "identifiers": [
    "vanId:252",
    "revere_sync:ae87ccde-7d82-4554-bded-56f305a4d323"
  ],
  "id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "family_name": "Doe",
  "given_name": "John",
  "additional_name": null,
  "honorific_prefix": null,
  "origin_system": "revere_sync",
  "party_identification": "Democratic",
  "preferred_language": "en",
  "source": null,
  "birthdate": {
    "year": 1999,
    "month": 11,
    "day": 22
  },
  "employer": null,
  "gender": null,
  "custom_fields": {
    "some_string": "here",
    "boolean_value": false,
    "number_value": 15
  },
  "ngp_van_sync_status": null,
  "mobile_sync_status": null,
  "created_at": "2017-05-23T09:30:49.569Z",
  "updated_at": "2017-05-23T09:30:49.569Z",
  "email_addresses": [
    {
      "address_type": "Work",
      "status": null,
      "primary": true,
      "address": "john@doe.com",
      "email_address_type": "work",
      "email_subscription_status": null,
      "updated_at": "2017-05-23T09:30:49.602Z"
    }
  ],
  "phone_numbers": [
    {
      "number_type": "Mobile",
      "primary": true,
      "number": "+1234567890",
      "description": null,
      "operator": null,
      "country": null,
      "sms_capable": false,
      "do_not_call": false,
      "phone_number_type": "mobile",
      "updated_at": "2017-05-23T09:30:49.604Z"
    }
  ],
  "postal_addresses": [
    {
      "location": {
        "latitude": null,
        "longitude": null,
        "accuracy": null
      },
      "address_type": "Home",
      "status": "Potential",
      "primary": true,
      "venue": null,
      "addressLine1": "515 Example St.",
      "addressLine2": null,
      "addressLine3": null,
      "locality": "Seattle",
      "region": "WA",
      "postal_code": 98036,
      "postal_code_plus_4": null,
      "country": "US",
      "language": "en",
      "latitude": null,
      "longitude": null,
      "accuracy": null,
      "last_verified_date": null,
      "postal_address_type": "home",
      "postal_address_status": "potential",
      "updated_at": "2017-05-23T09:30:49.604Z"
    }
  ]
}

The above returns JSON response of on match:

{
  "_links": {
    "self": [
      {
        "href": "/v2/api/people"
      },
      {
        "href": "http://sync.revmsg.net/api/people/df7ef2d4-12b9-45eb-ba8a-aa958a4c8ffd"
      }
    ]
  },
  "revere_sync_id": "df7ef2d4-12b9-45eb-ba8a-aa958a4c8ffd",
  "message": "Person Matched, use a PUT to update with new information."
}

Post Parameters

Post Parameters Type Required Description
given_name string true First Name or Given Name of a Person.
family_name string true Family or Last Name of a Person.
email_addresses array true Array of at least one primary Email object.
phone_numbers array true Array of at least one Phone Number object.
postal_addresses array false Array of at least one Phone Number object.

Note: primary:true should be the first item in the list of email_addresses, phone_numbers, postal_addresses.

Get Page of People

This route will allow you to fetch up to 10 person records at a time. You can increment the pages by providing a ?page={page_number} query string.

HTTP Request

GET https://sync.revmsg.net/people/{revere_sync_id}

curl "https://sync.revmsg.net/api/people"
  -H "Content-Type: application/json",
  -H "Accept: application/vnd.sync.v2+json",
  -H "Authorization: <token>"
var request = require("request");

var options = { method: "GET",
  url: "https://sync.revmsg.net/api/people",
  headers: 
   { "cache-control": "no-cache",
     "content-type": "application/json",
     "accept": "application/vnd.sync.v2+hal+json",
     "authorization": "Bearer <token>" 
   }
};

or by page

curl "https://sync.revmsg.net/api/people?page=2"
  -H "Content-Type: application/json",
  -H "Accept: application/vnd.sync.v2+json",
  -H "Authorization: <token>"
var request = require("request");

var options = { method: "GET",
  url: "https://sync.revmsg.net/api/people?page=2",
  headers: 
   { "cache-control": "no-cache",
     "content-type": "application/json",
     "accept": "application/vnd.sync.v2+hal+json",
     "authorization": "Bearer <token>" 
   }
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

Will reply with a list of people

{
  "_links": {
    "self": {
      "href": [
        "https://sync.revmsg.net/v2/api/people/df7ef2d4-12b9-45eb-ba8a-aa958a4c8ffd"
      ]
    },
    "next": {
      "href": "https://sync.revmsg.net/v2/api/people?page="
    },
    "curies": [
      {
        "name": "revere_sync",
        "href": "/rels/Revolution Messaging/{rel}",
        "templated": true
      }
    ]
  },
  "total_pages": 1,
  "per_page": 10,
  "page": 1,
  "next": null,
  "total_records": 1,
  "_embedded": {
    "revere_sync:people": {
      "_links": {
        "self": {
          "href": "https://sync.revmsg.net/v2/api/people/df7ef2d4-12b9-45eb-ba8a-aa958a4c8ffd"
        }
      },
      "revere_sync_id": "df7ef2d4-12b9-45eb-ba8a-aa958a4c8ffd",
      "identifiers": [
        "vanId:252",
        "revere_sync:df7ef2d4-12b9-45eb-ba8a-aa958a4c8ffd"
      ],
      "birthdate": {
        "year": 1999,
        "month": 11,
        "day": 22
      },
      "gender": "",
      "custom_fields": {
        "some_string": "here",
        "boolean_value": false,
        "number_value": 15
      },
      "ngp_van_sync_status": null,
      "mobile_sync_status": null,
      "id": "df7ef2d4-12b9-45eb-ba8a-aa958a4c8ffd",
      "family_name": "Person",
      "given_name": "Test",
      "additional_name": null,
      "honorific_prefix": null,
      "origin_system": "revere_sync",
      "party_identification": "Democratic",
      "preferred_language": "en",
      "source": null,
      "employer": null,
      "occupation": null,
      "gender_identity": null,
      "createdAt": "2017-06-30T02:13:05.377Z",
      "updatedAt": "2017-06-30T02:13:05.377Z",
      "created_at": "2017-06-30T02:13:05.377Z",
      "updated_at": "2017-06-30T02:13:05.377Z",
      "postal_addresses": [
        {
          "location": {
            "latitude": null,
            "longitude": null,
            "accuracy": null
          },
          "address_type": "Home",
          "status": "Potential",
          "primary": true,
          "venue": null,
          "addressLine1": "515 Example St.",
          "addressLine2": null,
          "addressLine3": null,
          "locality": "Seattle",
          "region": "WA",
          "postal_code": 98036,
          "postal_code_plus_4": null,
          "country": "US",
          "language": "en",
          "latitude": null,
          "longitude": null,
          "accuracy": null,
          "last_verified_date": null,
          "postal_address_type": "home",
          "postal_address_status": "potential",
          "updated_at": "2017-05-23T09:30:49.604Z"
        }
      ],
      "email_addresses": [
        {
          "address_type": "Work",
          "status": null,
          "primary": true,
          "address": "john@doe.com",
          "email_address_type": "work",
          "email_subscription_status": null,
          "updated_at": "2017-05-23T09:30:49.602Z"
        }
      ],
      "phone_numbers": [
        {
          "number_type": "Mobile",
          "primary": true,
          "number": "+1234567890",
          "description": null,
          "operator": null,
          "country": null,
          "sms_capable": false,
          "do_not_call": false,
          "phone_number_type": "mobile",
          "updated_at": "2017-05-23T09:30:49.604Z"
        }
      ],
      "profiles": [
        {
          "profile_provider": "Twitter",
          "id": "bc603110-1583-4620-9201-f619300b394b",
          "external_profile_id": null,
          "url": "https://twitter.com/johndoe15",
          "handle": "johndoe15",
          "updated_at": "2017-06-30T02:13:05.421Z"
        }
      ]
    }
  }
}
Parameter Type Description
page number The page to fetch next

Get One Person By Id

HTTP Request

GET https://sync.revmsg.net/people/{revere_sync_id}

Query Parameters

Parameter Type Description
revere_sync_id string The id of the person inside of Revere Sync.
curl "https://sync.revmsg.net/api/people/ae87ccde-7d82-4554-bded-56f305a4d323"
  -H "Content-Type: application/json",
  -H "Accept: application/vnd.sync.v2+json",
  -H "Authorization: <token>"
var request = require("request");

var options = { method: "POST",
  url: "https://sync.revmsg.net/api/people/ae87ccde-7d82-4554-bded-56f305a4d323",
  headers: 
   { "cache-control": "no-cache",
     "content-type": "application/json",
     "accept": "application/vnd.sync.v2+hal+json",
     "authorization": "Bearer <token>" }
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

The above returns JSON response of:

{
  "_links": {
    "self": {
      "href": "/v2/api/people/ae87ccde-7d82-4554-bded-56f305a4d323"
    }
  },
  "revere_sync_id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "identifiers": [
    "vanId:252",
    "revere_sync:ae87ccde-7d82-4554-bded-56f305a4d323"
  ],
  "id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "family_name": "Doe",
  "given_name": "John",
  "additional_name": null,
  "honorific_prefix": null,
  "origin_system": "revere_sync",
  "party_identification": "Democratic",
  "preferred_language": "en",
  "source": null,
  "birthdate": {
    "year": 1999,
    "month": 11,
    "day": 22
  },
  "employer": null,
  "gender": null,
  "custom_fields": {
    "some_string": "here",
    "boolean_value": false,
    "number_value": 15
  },
  "ngp_van_sync_status": null,
  "mobile_sync_status": null,
  "created_at": "2017-05-23T09:30:49.569Z",
  "updated_at": "2017-05-23T09:30:49.569Z",
  "email_addresses": [
    {
      "address_type": "Work",
      "status": null,
      "primary": true,
      "address": "john@doe.com",
      "email_address_type": "work",
      "email_subscription_status": null,
      "updated_at": "2017-05-23T09:30:49.602Z"
    }
  ],
  "phone_numbers": [
    {
      "number_type": "Mobile",
      "primary": true,
      "number": "+1234567890",
      "description": null,
      "operator": null,
      "country": null,
      "sms_capable": false,
      "do_not_call": false,
      "phone_number_type": "mobile",
      "updated_at": "2017-05-23T09:30:49.604Z"
    }
  ],
  "postal_addresses": [
    {
      "location": {
        "latitude": null,
        "longitude": null,
        "accuracy": null
      },
      "address_type": "Home",
      "status": "Potential",
      "primary": true,
      "venue": null,
      "addressLine1": "515 Example St.",
      "addressLine2": null,
      "addressLine3": null,
      "locality": "Seattle",
      "region": "WA",
      "postal_code": 98036,
      "postal_code_plus_4": null,
      "country": "US",
      "language": "en",
      "latitude": null,
      "longitude": null,
      "accuracy": null,
      "last_verified_date": null,
      "postal_address_type": "home",
      "postal_address_status": "potential",
      "updated_at": "2017-05-23T09:30:49.604Z"
    }
  ]
}

Update One Person

HTTP Request

PUT https://sync.revmsg.net/people/{revere_sync_id}

curl -X PUT \
  https://sync.revmsg.net/api/people/ae87ccde-7d82-4554-bded-56f305a4d323 \
  -H 'Accept: application/vnd.sync.v2+hal+json' \
  -H 'Authorization: Bearer <token>' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
  "given_name":"John",
  "family_name":"Doe",
  "identifiers": [
      "vanId:252",
      "salsaId:54654-56456-46262"
  ],
  "party_identification":"Democratic",
  "custom_fields":{
    "some_string":"here",
    "boolean_value":true,
    "number_value":15,
    "new_field":"wow"
  },
  "postal_addresses":[
    {
      "locality": "Seattle",
      "region": "WA",
      "addressLine1": "Po Box",
      "addressLine2": "15",
      "postal_code": "98036",
      "address_type":"Mailing"
    }   
  ],
  "phone_numbers":[
      {
        "number":"+19876543321",
        "number_type":"Home",
        "sms_capable":false
      }
  ],
  "email_addresses":[
      {
        "address":"joe_awesome@gmail.com",
        "address_type":"Personal"
      }
  ]
}'
var request = require("request");

var options = { method: "POST",
  url: "https://sync.revmsg.net/api/people/ae87ccde-7d82-4554-bded-56f305a4d323",
  headers: 
   { "cache-control": "no-cache",
     "content-type": "application/json",
     "accept": "application/vnd.sync.v2+hal+json",
     "authorization": "Bearer <token>" },
  body: {
    given_name:"John",
    family_name:"Doe",
    identifiers: [
        "vanId:252",
        "salsaId:54654-56456-46262"
    ],
    party_identification:"Democratic",
    custom_fields:{
      some_string:"here",
      boolean_value:true,
      number_value:15,
      new_field:"wow"
    },
    postal_addresses:[
      {
        locality: "Seattle",
        region: "WA",
        addressLine1: "Po Box",
        addressLine2: "15",
        postal_code: "98036",
        address_type:"Mailing"
      }   
    ],
    phone_numbers:[
        {
          number:"+19876543321",
          number_type:"Home",
          sms_capable:false
        }
    ],
    email_addresses:[
        {
          address:"joe_awesome@gmail.com",
          address_type:"Personal"
        }
    ] 
  }
};

The above returns JSON response of:

{
  "_links": {
    "self": [
      {
        "href": "/v2/api/people"
      },
      {
        "href": "http://sync.revmsg.net/api/people/ae87ccde-7d82-4554-bded-56f305a4d323"
      }
    ]
  },
  "revere_sync_id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "identifiers": [
    "vanId:252",
    "salsaId:54654-56456-46262",
    "revere_sync:ae87ccde-7d82-4554-bded-56f305a4d323"
  ],
  "id": "ae87ccde-7d82-4554-bded-56f305a4d323",
  "family_name": "Doe",
  "given_name": "John",
  "additional_name": null,
  "honorific_prefix": null,
  "origin_system": "revere_sync",
  "party_identification": "Democratic",
  "preferred_language": "en",
  "source": null,
  "birthdate": {
    "year": 1999,
    "month": 11,
    "day": 22
  },
  "employer": null,
  "gender": null,
  "custom_fields": {
    "some_string": "here",
    "boolean_value": false,
    "number_value": 15,
    "new_field":"wow"
  },
  "ngp_van_sync_status": null,
  "mobile_sync_status": null,
  "created_at": "2017-05-23T09:30:49.569Z",
  "updated_at": "2017-05-23T09:30:49.569Z",
  "email_addresses": [
    {
      "address_type": "Work",
      "status": null,
      "primary": true,
      "address": "john@doe.com",
      "email_address_type": "work",
      "email_subscription_status": null,
      "updated_at": "2017-05-23T09:30:49.602Z"
    },

    {
      "address_type": "Personal",
      "status": null,
      "primary": false,
      "address": "joe_awesome@gmail.com",
      "email_address_type": "personal",
      "email_subscription_status": null,
      "updated_at": "2017-05-23T09:30:49.603Z"
    },
  ],
  "phone_numbers": [
    {
      "number_type": "Mobile",
      "primary": true,
      "number": "+1234567890",
      "description": null,
      "operator": null,
      "country": null,
      "sms_capable": false,
      "do_not_call": false,
      "phone_number_type": "mobile",
      "updated_at": "2017-05-23T09:30:49.604Z"
    },
    {
      "number_type": "Home",
      "primary": false,
      "number": "+19876543321",
      "description": null,
      "operator": null,
      "country": null,
      "sms_capable": false,
      "do_not_call": false,
      "phone_number_type": "home",
      "updated_at": "2017-05-23T09:30:49.604Z"
    }
  ],
  "postal_addresses": [
    {
      "location": {
        "latitude": null,
        "longitude": null,
        "accuracy": null
      },
      "address_type": "Home",
      "status": "Potential",
      "primary": true,
      "venue": null,
      "addressLine1": "515 Example St.",
      "addressLine2": null,
      "addressLine3": null,
      "locality": "Seattle",
      "region": "WA",
      "postal_code": 98036,
      "postal_code_plus_4": null,
      "country": "US",
      "language": "en",
      "latitude": null,
      "longitude": null,
      "accuracy": null,
      "last_verified_date": null,
      "postal_address_type": "home",
      "postal_address_status": "potential",
      "updated_at": "2017-05-23T09:30:49.604Z"
    },
    {
      "location": {
        "latitude": null,
        "longitude": null,
        "accuracy": null
      },
      "address_type": "Home",
      "status": "Potential",
      "primary": false,
      "venue": null,
      "addressLine1": "Po Box",
      "addressLine2": "15",
      "addressLine3": null,
      "locality": "Seattle",
      "region": "WA",
      "postal_code": 98036,
      "postal_code_plus_4": null,
      "country": null,
      "language": "en",
      "latitude": null,
      "longitude": null,
      "accuracy": null,
      "last_verified_date": null,
      "postal_address_type": "home",
      "postal_address_status": "potential",
      "updated_at": "2017-05-23T09:30:49.605Z"
    }
  ]
}

Post Parameters

Post Parameters Type Required Description
given_name string false First Name or Given Name of a Person.
family_name string false Family or Last Name of a Person.
email_addresses array false Array of at least one primary Email object. If only one is provided that becomes the primary.
phone_numbers array false Array of at least one Phone Number object. If only one is provided that becomes the primary.
postal_addresses array false Array of at least one Phone Number object. If only one is provided that becomes the primary.

Constitutent

Note: This endpoint does not require Authentication and is designed for public use.

Note: This endpoint is not OSDI enabled.

Constituents are a legacy actor in Sync and actions by triggers are preformed on them. It is possible to create constituents with GET and PUT requests but this method is highly discouraged and only exists for backwards compatibility with V1. All constituents should be created using the POST method. This endpoint is used by Sync V2 forms and should be used if creating a custom interaction with Sync V2.

HTTP Request

POST https://sync.revmsg.net/constituent/{access_token}

Create a constituent

curl -X POST \
  https://sync.revmsg.net/constituent/ba6dc8c06b3aa6a461fbae850a26dda5 \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
    "name":"Steve Bob",
    "firstname":"Steve",
    "lastname":"Bob",
    "address":"555 Fake St.",
    "address_two":"APT 24",
    "city":"Seattle",
    "state":"WA",
    "zipcode":"98045",
    "email":"steve@steve.com",
    "home_phone":"1-555-555-5555",
    "msisdn":"1-555-555-5555",
    "employer":"Steve Company Inc",
    "metadata": {
        "source":"facebook",
        "emailOptInStatus":"I"
        },
    "tags":"amazingpeople2016"
}'
var request = require("request");

var options = { method: 'POST',
  url: 'https://sync.revmsg.net/constituent/ba6dc8c06b3aa6a461fbae850a26dda5',
  headers: 
   { 'postman-token': 'e072e825-97a3-6953-5641-a75badc9dfb6',
     'content-type': 'application/json',
     'Accept': 'application/vnd.sync.v2+json',
     'cache-control': 'no-cache' },
  body: 
   { name: 'Steve Bob',
     firstname: 'Steve',
     lastname: 'Bob',
     address: '555 Fake St.',
     address_two: 'APT 24',
     city: 'Seattle',
     state: 'WA',
     zipcode: '98045',
     email: 'steve@steve.com',
     home_phone: '1-555-555-5555',
     msisdn: '1-555-555-5555',
     employer: 'Steve Company Inc',
     metadata: { source: 'facebook', emailOptInStatus: 'I' },
     tags: 'amazingpeople2016' },
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

JSON response of on create

{
  "error":false,
  "message":"Contact accepted.",
  "id":"57d723cbd9dc8cdc5ad00191"
}

Provide an access token to send with constituent data

Parameter Type Required Description
access_token String True Access Token Hash

At least one paramater is required to post data. Below are the allowed fields for a constituent. The tag parameter is required to activate the triggers which will forward information to Sync’s integrations. Each tag can be a string or an array of strings.

Post Parameters

Properties Type Required Description
name String False Full name, will be created from firstname and lastname automatically if possible.
firstname String False First Name of Constituent
lastname String False Last Name of Constituent
address String False Primary Street Address
address_two String False Secondary Street Address
city String False City of Constituent
state String False Two Char String ( IE: WA )
zipcode String False Five Digit Zip Code and four seperated by -. 98036 or 98036-1513 are OK.
email String False Email of Constituent
work_email String False Work Email of Constituent
phone String False Phone of Constituent, will populate msisdn when phone provided.
msisdn String False Mobile Phone number of Constituent, gets populated by phone if only phone is provided.
work_phone String False Work Phone number of Constituent
home_phone String False Home Phone number of Constituent
employer String False Employer of Constituent
work_address String False Work address of Constituent.
work_address_two String False Work address, second line of Constituent
work_city String False Work city of Constituent.
work_state String False Work State, TWO Char String (IE: WA).
work_zipcode String False Work Zip Code, a five digit zip code and four seperated by -. 98036 or 98036-1513 are OK.
mail_address String False Mail address of Constituent.
mail_address_two String False Mail address, second line of Constituent
mail_city String False Mail city of Constituent.
mail_state String False Mail State, TWO Char String (IE: WA).
mail_zipcode String False Mail Zip Code, a five digit zip code and four seperated by -. 98036 or 98036-1513 are OK.
vote_address String False Voter address of Constituent.
vote_address_two String False Voter address, second line of Constituent
vote_city String False Voter city of Constituent.
vote_state String False Voter State, TWO Char String (IE: WA).
vote_zipcode String False Voter Zip Code, a five digit zip code and four seperated by -. 98036 or 98036-1513 are OK.
metadata Object False Metadata object (see table), IE: source:string for an ActionKit integration
tags String False Can be one String or an Array of Strings used to trigger actions setup inside of Sync.

Metadata Object

Properties Type Required Description
source string False A string, such as facebook, twitter, EveryActionForm etc.
preferredPhone string False Must be msisdn, work_phone, or home_phone and field must be present.
preferredEmail string False Must be email or work_email and field must be present.
phoneOptInStatus string False Must be I for in or O for out. Default is O.
emailOptInStatus string False Must be I for in or O for out. Default is O

Services

Note: This endpoint is not OSDI enabled.

Revere Mobile Services

This is the entry point to retrive Revere Mobile Services and Revere Mobile Flows.

The Revere Mobile Service Object

Attribute Type Description
id ObjectId Unique ID for the Mobile Service.
name string Name for the Mobile Service
revere_mobile_shortcode_number string Shortcode Number that the subscriber interacts with.
status string Status of Service, only Active will be allowed to be used
createdAt datetime Automatically generated date/time when user is created.
updatedAt datetime Automatically updated date/time when user is updated.

The Revere Mobile Flow Object

Attribute Type Description
id ObjectId Unique ID for the Mobile Flow.
name string Name for the Mobile Service
revere_mobile_shortcode_number string Shortcode Number that the subscriber interacts with.
revere_mobile_service_id ObjectId Unique ID for the Mobile Service.
created_at datetime Automatically generated date/time when user is created.
updated_at datetime Automatically updated date/time when user is updated.

The Terms and Conditions Object

Attribute Type Description
client_shortname string Short Legal name of the user or user of Revere Mobile.
shortcode_number string Shortcode Number that the subscriber interacts with.
public_terms_and_conditions_url string Endpoint for the Terms & Conditions Link
html string HTML String to be used with a Revere Mobile Signup Form

Get All Revere Mobile Services

HTTP Request

GET https://sync.revmsg.net/api/revere_mobile/services

curl -X GET \
  https://sync.revmsg.net/api/revere_mobile/services \
  -H 'accept: application/vnd.sync.v2+json' \
  -H 'authorization: Bearer <token>' \
  -H 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://sync.revmsg.net/api/revere_mobile/services',
  headers: 
   { 'content-type': 'application/json',
     accept: 'application/vnd.sync.v2+json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});


Will reply with a list of services

[
    {
        "updatedAt": "2017-10-27T08:37:25.680Z",
        "createdAt": "2016-10-07T21:26:39.834Z",
        "name": "Example Mobile Service",
        "revere_mobile_shortcode_number": "225568",
        "status": "Active",
        "id": "57f8130f997eaf000a5baae2"
    },
    {
        "updatedAt": "2017-11-01T12:33:15.801Z",
        "createdAt": "2017-11-01T12:33:15.801Z",
        "name": "Example 2 Mobile Service",
        "revere_mobile_shortcode_number": "62262",
        "status": "Active",
        "id": "19f9rf0b2b35d2000d9b21cd"
    }
]

Get One Mobile Service By Id

HTTP Request

GET https://sync.revmsg.net/api/revere_mobile/services/{id}

Query Parameters

Parameter Type Description
id ObjectId The id of the service.
curl -X GET \
  https://sync.revmsg.net/api/revere_mobile/services/19f9rf0b2b35d2000d9b21cd \
  -H 'accept: application/vnd.sync.v2+json' \
  -H 'authorization: Bearer <token>' \
  -H 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://sync.revmsg.net/api/revere_mobile/services/19f9rf0b2b35d2000d9b21cd',
  headers: 
   { 'content-type': 'application/json',
     accept: 'application/vnd.sync.v2+json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});


Will reply with one service

{
  "updatedAt": "2017-11-01T12:33:15.801Z",
  "createdAt": "2017-11-01T12:33:15.801Z",
  "name": "Example 2 Mobile Service",
  "revere_mobile_shortcode_number": "62262",
  "status": "Active",
  "id": "19f9rf0b2b35d2000d9b21cd"
}

Get A Service’s Mobile Flows

HTTP Request

GET https://sync.revmsg.net/api/revere_mobile/services/{id}/mobile_flows

curl -X GET \
  https://sync.revmsg.net/api/revere_mobile/services/19f9rf0b2b35d2000d9b21cd/mobile_flows \
  -H 'accept: application/vnd.sync.v2+json' \
  -H 'authorization: Bearer <token>' \
  -H 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://sync.revmsg.net/api/revere_mobile/services/19f9rf0b2b35d2000d9b21cd/mobile_flows',
  headers: 
   { 'content-type': 'application/json',
     accept: 'application/vnd.sync.v2+json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

Will reply with mobile flows

[
    {
        "name": "Example Flow 1",
        "created_at": "2017-10-31T16:01:59.576Z",
        "updated_at": "2017-10-31T16:01:59.576Z",
        "id": "16f89542e4b0e9c3e9d6ca7a"
    },
    {
        "name": "Example Flow 2",
        "created_at": "2017-10-31T16:01:16.589Z",
        "updated_at": "2017-10-31T16:01:16.589Z",
        "id": "16f8916ae4b0e9c3e9d67b2e"
    },
    {
        "name": "Example Flow 3",
        "created_at": "2017-10-31T16:01:16.605Z",
        "updated_at": "2017-10-31T16:01:16.605Z",
        "id": "16f89428e4b0e9c3e9d6c72c"
    },
    {
        "name": "Example Flow 4",
        "created_at": "2017-10-31T16:01:16.640Z",
        "updated_at": "2017-10-31T16:01:16.640Z",
        "id": "16f67580e4b0fd80e639e64b"
    },
    {
        "name": "Example Flow 5",
        "created_at": "2017-10-31T16:01:16.671Z",
        "updated_at": "2017-10-31T16:01:16.671Z",
        "id": "16f67f62e4b0fd80e63a0725"
    }
]

Get Revere Mobile Flow Info

It is also possible to trace back a mobile flow to it’s service. This is useful for getting the Terms & Conditions for a Revere Mobile Service.

HTTP Request

GET https://sync.revmsg.net/api/revere_mobile/mobile_flows/{id}

Query Parameters

Parameter Type Description
id ObjectId The id of the Mobile Flow.
curl -X GET \
  https://sync.revmsg.net/api/revere_mobile/mobile_flows/16f89542e4b0e9c3e9d6ca7a \
  -H 'accept: application/vnd.sync.v2+json' \
  -H 'authorization: Bearer <token>' \
  -H 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://sync.revmsg.net/api/revere_mobile/mobile_flows/16f89542e4b0e9c3e9d6ca7a',
  headers: 
   { 'content-type': 'application/json',
     authorization: 'Bearer <token>',
     accept: 'application/vnd.sync.v2+json' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

Will reply with

{
    "name": "Example Flow 1",
    "id": "16f89542e4b0e9c3e9d6ca7a",
    "revere_mobile_service_id": "19f9rf0b2b35d2000d9b21cd",
    "revere_mobile_shortcode_number": "62262"
}

Get A Service’s Terms & Conditions

This is the entry point to retrive a Revere Mobile Services’s Terms & Conditions. This requires a Revere Mobile Service to operate.

HTTP Request

GET https://sync.revmsg.net/api/revere_mobile/services/{id}/terms_and_conditions

curl -X GET \
  https://sync.revmsg.net/api/revere_mobile/services/19f9rf0b2b35d2000d9b21cd/terms_and_conditions \
  -H 'accept: application/vnd.sync.v2+json' \
  -H 'authorization: Bearer <token>' \
  -H 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url: 'https://sync.revmsg.net/api/revere_mobile/services/19f9rf0b2b35d2000d9b21cd/terms_and_conditions',
  headers: 
   { 'content-type': 'application/json',
     accept: 'application/vnd.sync.v2+json',
     authorization: 'Bearer <token>' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

Will reply with the Terms And Conditions

{
    "client_shortname": "Example Client",
    "shortcode_number": "62262",
    "public_terms_and_conditions_url": "https://sync.revmsg.net/public/terms-and-conditions/8b242a3e-3e33-4954-8b01-64a92c9f671c/62262",
    "html": "<p>Mobile alerts from Example Client messages. Msg &amp; data rates may apply.<b>Text STOP to 62262 to stop receiving messages.Text HELP to 62262 for more information.</b><br> <a href=\"https://sync.revmsg.net/public/terms-and-conditions/8b242a3e-3e33-4954-8b01-64a92c9f671c/62262\" target=\"_blank\">Terms &amp; Conditions</a>"
}

V1 Forms

This is a legacy API, please use V2 Forms if possible.

Getting Started

These forms consist of HTML and JavaScript components. A sample form would start as:

<div class="revmsg-wrapper"> 
 <form class="revmsg-form" method="post" action="https://sync.revmsg.net/constituent/<access token>/" name="revmsg-form">
      <div class="revmsg-failure" style="display: none;">Sorry, but we failed to add you to the list. Please try again or contact <a href="tel:+18887806763">1.888.780.6763</a></div> 
<fieldset id="signup"> 

  <div class="text">
    <label for="phone">Cell Phone Number</label>
    <input type="text" id="cellphone" name="phone" placeholder="Cell Phone Number">
  </div>

 </fieldset> 

    <div class="submit">
      <input type="hidden" name="triggers" value="example_trigger">
      <input class="revmsg-submit-btn" type="submit" value="submit">
    </div> 

 </form> 

    <div class="revmsg-fdbk">
        <div class="revmsg-loading" style="display: none;">...loading</div>
        <div class="revmsg-success" style="display: none;">Thanks for signing up!</div>
      </div>
     </div>
 <script src="https://sync.revmsg.net/form/<FULL FORM ID>"></script>

The key components here are the HTML form with a name of triggers that allows sync to run each service setup. These form are generated and provided to you in general so you will not have to write this html or enter the Form ID. If you require more customization the constituent api will be more useful.

Redirects

Sync V1 Forms have the ability to be configured to redirect to another page after submission.

Ensure the revmsgConfig is declared before the sync javascript src tag

<script>
  revmsgConfig = {
      "redirect": "https://revolutionmessaging.com"
  }
</script>
<script src="https://sync.revmsg.net/form/<FULL FORM ID>">;</script>

Callbacks

Sync V1 Forms also fire a callback upon submission with data and error details if they exist.

<script>
revmsgConfig = {
  callback: function(data) {
    if(data.error) {
    // there was a problem, do not fire conversion code.
    // maybe show another error state/message
    } else {
    // fire conversion pixel embed
    // show a success message
    // show "share this functionality"
    // or other "YAY!" thing here.
    }
  }
}
</script>
<script src="https://sync.revmsg.net/form/<FULL FORM ID>">;</script>

V2 Forms

Developer Ready Sync Forms

Getting Started

Sync V2 Forms are built to be backwards compatible and compatible with currently rendering forms that are out in the wild are designed to operate the same. This means that even existing forms can get the features of new ones as they are added.

The most simple way to start is to let the form render itself using the following html.

First ensure you have an HTML page / website you want to use your Sync form.

<div id="revere-sync"></div>
<script async src="https://sync.revmsg.net/form/v2/<FULL FORM ID>"></script>

So an example form with an ID will look like

<div id="revere-sync"></div>
<script async src="https://sync.revmsg.net/form/v2/79826d9f-3930-4630-82ae-d1e25b5bfa6e"></script>

The form will render in the innerHTML of the #revere-sync div.

If you would like to use multiple forms per page simply create a div with a data-sync-form-id=<FULL FORM ID> attribute. For example:

<div data-sync-form-id="79826d9f-3930-4630-82ae-d1e25b5bfa6e"></div>

The form will render in the innerHTML of this div.

If you do not include the first form with the id of revere-sync you will not be able to use multiple forms. This data structure is to allow non-conflicting renders with existing sync v2 forms that already are spread accross the web.

This is the basics of how to apply a sync form and use multiple per site.

Structure of A Form

Sync V2 Forms have two structures, first is without a data-sync-form-id these a fairly easy to understand.

<div id="revere-sync">
   <form class="rsform" id="revere-sync-form" method="post" action="https://revere-sync-v2-stage.herokuapp.com/constituent/<access token>" name="revere-sync">
      <div class="rsform__field--required">
         <label for="name" class="rsform__field--label">Full Name *</label>
         <input id="name" class="rsform__field--text" name="name" placeholder="Full Name" required="" type="text">
      </div>
      <div class="rsform__field--required">
         <label for="email" class="rsform__field--label">Email *</label>
         <input id="email" class="rsform__field--email" name="email" placeholder="you@yourdomain.com" required="" type="email">
      </div>
      <div class="rsform__field">
         <label for="state" class="rsform__field--label">State </label>
         <select id="state" class="rsform-field--select" name="state">
            <option value="select-one">Select One</option>
            <option value="AK">AK</option>
            <!-- other states here of course-->
         </select>
      </div>
      <div class="rsform--custom_html">
         <h3>Some html here.</h3>
      </div>
      <div class="rsform--submit">
         <input class="sync-hidden-input" name="tags" value="test_1" type="hidden">
         <input class="sync-hidden-input" name="tags" value="test_2" type="hidden">
         <input id="sync-submit-button" class="rsform--submit__btn" value="Custom Submit Text" type="submit">
      </div>
   </form>
</div>

The important part is to notice the id. These are common field names that could conflict with ids that already exist on the page. email is a common name for an id so if there are errors please check to see if you already have a conflicting id on the page.

The tags of a sync form (hidden in the sync-hidden-input class) are how triggers are ran. When sync accepts these sync will run the various configured triggers for that tag.

An example with two tags active on a sync form will look like:

<div id="revere-sync">
   <form class="rsform" id="revere-sync-form" method="post" action="https://revere-sync-v2-stage.herokuapp.com/constituent/<access token>" name="revere-sync">
      <div class="rsform__field--required">
         <label for="name" class="rsform__field--label">Full Name *</label>
         <input id="name" class="rsform__field--text" name="name" placeholder="Full Name" required="" type="text">
      </div>
      <div class="rsform__field--required">
         <label for="email" class="rsform__field--label">Email *</label>
         <input id="email" class="rsform__field--email" name="email" placeholder="you@yourdomain.com" required="" type="email">
      </div>
      <div class="rsform__field">
         <label for="state" class="rsform__field--label">State </label>
         <select id="state" class="rsform-field--select" name="state">
            <option value="select-one">Select One</option>
            <option value="AK">AK</option>
            <!-- other states here of course-->
         </select>
      </div>
      <div class="rsform--custom_html">
         <h3>Some html here.</h3>
      </div>
      <div class="rsform--submit">
         <input class="sync-hidden-input" name="tags" value="test_1" type="hidden">
         <input class="sync-hidden-input" name="tags" value="test_2" type="hidden">
         <input id="sync-submit-button" class="rsform--submit__btn" value="Custom Submit Text" type="submit">
      </div>
   </form>
</div>

Sync V2 Forms with Data IDs

A data-sync-form-id is the second type of sync form. These will have the id of the form at the end of each field id as well as on the form itself. Stick to class names or [data-sync-form-id="<FULL FORM ID>"] > <css selector> in you css if you need to style a form by it’s id.

Example data-sync-form with id attached

<div type="revere-sync-form" data-sync-form-id="79826d9f-3930-4630-82ae-d1e25b5bfa6e">
   <form class="rsform" id="revere-sync-form-79826d9f-3930-4630-82ae-d1e25b5bfa6e" method="post" action="https://revere-sync-v2-stage.herokuapp.com/constituent/<access token>" name="revere-sync">
      <div class="rsform__field--required">
         <label for="name" class="rsform__field--label">Full Name *</label>
         <input id="name-79826d9f-3930-4630-82ae-d1e25b5bfa6e" class="rsform__field--text" name="name" placeholder="Full Name" required="" type="text">
      </div>
      <div class="rsform__field--required">
         <label for="email" class="rsform__field--label">Email *</label>
         <input id="email-79826d9f-3930-4630-82ae-d1e25b5bfa6e" class="rsform__field--email" name="email" placeholder="you@yourdomain.com" required="" type="email">
      </div>
      <div class="rsform__field">
         <label for="state" class="rsform__field--label">State </label>
         <select id="state-79826d9f-3930-4630-82ae-d1e25b5bfa6e" class="rsform-field--select" name="state">
            <option value="select-one">Select One</option>
            <option value="AK">AK</option>
            <!-- other states here of course-->
         </select>
      </div>
      <div class="rsform--custom_html">
         <h3>Some html here.</h3>
      </div>
      <div class="rsform--submit">
         <input class="sync-hidden-input" name="tags" value="test_en_page_1" type="hidden">
         <input id="sync-submit-button-79826d9f-3930-4630-82ae-d1e25b5bfa6e" class="rsform--submit__btn" value="Custom Submit Text" type="submit">
      </div>
   </form>
</div>

Fancy Rendering Methods

Since Sync forms replace the innerHTML you can include HTML before the sync form will load. For example a CSS loading spinner is a great thing to place into a sync form.

Place loading HTML inside the parent div

<div id="revere-sync">
  <div class="loader">
   <!-- put your fancy css loading spinner here -->
  </div> 
</div>

with an ID

<div type="revere-sync-form" data-sync-form-id="a66b847e-8d4c-44c4-ad13-d7d90d1d8b63">
  <div class="loader">
    <!-- put your fancy css loading spinner here -->
  </div> 
</div>

Sync will then replace your HTML when the form has loaded. This keeps sync forms compatible with most websites in terms of styles.

Validation and Required Errors

Sync forms will always apply the same classes for errors as well as add p tags into the form to alert the user something is wrong.

<div class="rsform__field--required">
  <label for="email" class="rsform__field--label">Email *</label>
  <input id="email" class="rsform__field--email" name="email" placeholder="you@yourdomain.com" required="" type="email">
  <p id="email-error-missing" class="rsform__field--error">Email is required</p>
</div>
<div class="rsform__field--invalid">
  <label for="email" class="rsform__field--label">Email *</label>
  <input id="email" class="rsform__field--email" name="email" placeholder="you@yourdomain.com" required="" type="email">
  <p id="email-error" class="rsform__field--error">Email is invalid.</p>
</div>

NOTE: These modifiers will never mix, as an empty field is not invalid if it is required.

Events

Each Sync V2 form can trigger events on the document. Examples using jQuery v2 or v3.

On Load

This event is fired by each form on the page after it has been written to the DOM, one for the main sync form and others with it’s ids.

<script>
$(document).ready(function() {
  $(document).on("sync_form_ready", function() {
    // do something here
  });
});
</script>

To listen to the event of a sync form with a data-sync-form-id:

<script>
$(document).ready(function() {
  $(document).on("sync_form_ready-<FULL FORM ID>", function() {
    // do something here
  });
});
</script>

in our example form

<script>
$(document).ready(function() {
  $(document).on(
    "sync_form_ready-79826d9f-3930-4630-82ae-d1e25b5bfa6e",
    function() {
      // do something here
    }
  );
});
</script>

On Submit

This event fires when a user clicks the Submit button and data is valid in the form.

<script>
$(document).ready(function() {
  $(document).on("sync_form_submit_start", function() {
    // do something here
  });
});
</script>

To listen to the event of a sync form with a data-sync-form-id:

<script>
$(document).ready(function() {
  $(document).on("sync_form_submit_start-<FULL FORM ID>", function() {
    // do something here
  });
});
</script>

so in our example form

<script>
$(document).ready(function() {
  $(document).on(
    "sync_form_submit_start-79826d9f-3930-4630-82ae-d1e25b5bfa6e",
    function() {
      // do something here
    }
  );
});
</script>

On Submit Success

Fires an event when the form has been succesfully submited and data has made it to sync.

<script>
$(document).ready(function() {
  $(document).on("sync_form_success", function() {
    // do something here
  });
});
</script>

To listen to the event of a sync form with a data-sync-form-id:

<script>
$(document).ready(function() {
  $(document).on("sync_form_success-<FULL FORM ID>", function() {
    // do something here
  });
});
</script>

so in our example form

<script>
$(document).ready(function() {
  $(document).on(
    "sync_form_success-79826d9f-3930-4630-82ae-d1e25b5bfa6e",
    function() {
      // do something here
    }
  );
});
</script>

On Submit Fail

This event fires when there was an issue sending the data to Sync, usually from a server error.

<script>
$(document).ready(function() {
  $(document).on("sync_form_submit_fail", function() {
    // do something here
  });
});
</script>

To listen to the event of a sync form with a data-sync-form-id:

<script>
$(document).ready(function() {
  $(document).on("sync_form_submit_fail-<FULL FORM ID>", function() {
    // do something here
  });
});
</script>

in our example form

<script>
$(document).ready(function() {
  $(document).on(
    "sync_form_submit_fail-79826d9f-3930-4630-82ae-d1e25b5bfa6e",
    function() {
      // do something here
    }
  );
});
</script>

Google Tag Features

Sync V2 forms also push in events to the dataLayer for Google Tag manager to hook into. This happens at the Submit event after the form has been succesfully submitted.

No data-id attribute

<script>
  window.dataLayer.push({ event: "sync_form_conversion" });
</script>

To listen to the event of a sync form with a data-sync-form-id:

<script>
  window.dataLayer.push({ event: "sync_form_conversion-<FULL FORM ID>" });
</script>

in our example form

<script>
  window.dataLayer.push({ event: "sync_form_conversion-79826d9f-3930-4630-82ae-d1e25b5bfa6e" });
</script>

Facebook Pixel Features

Sync V2 forms will always fire facebook pixel events as a standard feature. This will require the facebook pixel id to be configured when building the sync form. This will fire the track feature of the facebook sdk and contain a data value of CompleteRegistration. This will also use the advanced tracking feature where user information is submitted to facebook.

This requries the facebook fpq be present on the same site as the sync form. Sync will reinit the fbq sdk with it’s own configured facebook pixel id, pass the advanced tracking data, then finally pass the CompleteRegistration event via:

Facebook CompleteRegistration Event

<script>
  window.fbq(
    "init",
    facebook_pixel_id, // configured facebook pixel id
    facebookData // advanced tracking data
  );

  window.fbq("track", "CompleteRegistration"); // registration event
</script>

With these events you should be able to take full advantage of V2 Forms! 🚀