EveryAction 8 API

VAN

Overview

VAN is the application which powers EveryAction 8.

The VAN’s RESTful API exposes resources as varied as those available through the VAN’s user interface. Unless specified otherwise, these endpoints only respond to and return JSON. Most REST conventions are followed: GET /resources lists all resources in the authenticated context, GET /resources/{id} gets the details of a specific object, POST /resources creates a new object, PUT /resources/{id} updates a specific object, and DELETE /resources/{id} deletes or suppresses a specific object. Some endpoints also support the PATCH HTTP verb for partial resource updates.

Request Data

Unless specified otherwise, these endpoints only respond to and return JSON. Any request containing JSON data must also set the Content-Type header to application/json.

Authentication

Before using the API, you will need to know your Application Name and API Key. The Application Name is a short string that identifies your application (e.g., acmeCrmProduct) and the API Key is a string that identifies the specific context to which API requests should resolve. Specifically, it identifies an API user in an instance, database tab, and committee—the same information that is determined during the typical VAN login process.

The API key will look like the concatenation of a GUID, a | and a 0 or 1 (e.g., 7c9e6679-7425-40de-944b-e07fc1f90ae7|1). Use 0 to work in VoterFile mode, and 1 to work in MyCampaign mode. Because the API key is connected to a specific context, the API will only return data available to that context.

Note:

API keys are connected to specific developers and applications. Do not share or re-use an API key for different applications nor expose it via client-side scripts or public code repositories.

To authenticate your API requests, use Basic HTTP authentication and set the username to the Application Name and password to the API Key. Most programming frameworks supports basic authentication out of the box.

The following is a very basic NodeJS example of an authenticated request:

var request = require('request');
var username = 'acmeCrmProduct';
var password = '7c9e6679-7425-40de-944b-e07fc1f90ae7|1';
var options = {
  url: 'https://api.securevan.com/v4/[resource name here]',
  auth: {
    user: username,
    password: password
  },
  ...
};
request(options, function (err, res, body) {
  if (err) {
    console.dir(err);
    return;
  }
  console.dir('headers', res.headers);
  console.dir('status code', res.statusCode);
  console.dir(body);
});

The following is a basic C# example of an authenticated request:

string username = "acmeCrmProduct";
string password = "7c9e6679-7425-40de-e07fc1f90ae7|1";
string url = "https://api.securevan.com/v4/[resource name here]";

using(var client = new HttpClient())
{
  client.DefaultRequestHeaders.Add("Authorization", 
    "Basic " + Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(
      string.Format("{0}:{1}", username, password))));

  var response = client.GetAsync(url).Result;
}

Errors

All API calls use the NGP VAN standard error format for returning errors. The response will always have an HTTP status code of 400 or greater and a single property called errors which is an array of one or more standard Error objects. These objects have the following properties:

Property Description
code Required; a descriptive, all caps, underscore-separated string (e.g., CHECK_OUTS_TOO_FREQUENT)
text Required; a description of the error that is suitable for display to end users
properties Optional; an array containing the path(s) to one or more of the request object’s offending properties using dot notation (e.g., primaryAddress.streetAddress). If the offending property is on an object in an array, the property will use square brackets and a zero based index of the item in the original array.
referenceCode Optional; a string containing a reference to the request’s error
hint Optional; typically a regular expression used to evaluate the property
resourceUrl Optional; a link to technical resources to assist developer with resolving the error

In the following example, an error is reported that is not tied to a specific property.

{
  "errors": [
    {
      "text": "Events are not supported in this database",
      "code": "EVENTS_NOT_SUPPORTED_IN_DB"
    }
  ]
}

In the following example, a single property of a request has failed.

{
  "errors": [
    {
      "properties": [
        "creditCardNumber"
      ],
      "text": "Credit card number must be digits only",
      "code": "INVALID_PARAMETER"
    }
  ]
}

In the following example, two properties of the request contributed to a single failure.

{
  "errors": [
    {
      "properties": [
        "dateBegin",
        "dateEnd"
      ],
      "text": "dateEnd must come after dateBegin",
      "code": "INVALID_PARAMETER"
    }
  ]
}

The following example illustrates how to report a failure in the second phone (zero-based index) in a person object’s array of phones.

{
  "errors": [
    {
      "properties": [
        "phones[1].extension"
      ],
      "text": "Extensions must be numeric",
      "code": "INVALID_PARAMETER"
    }
  ]
}

In the following example, the request’s phone number is invalid. The regular expression used to validate is provided as a hint.

{
  "errors": [
    {
      "properties": [
        "phones[0].number"
      ],
      "text": "A valid phone number is required",
      "hint": "^1?[2-9][0-8]\d[2-9]\d{6,6}$",
      "code": "INVALID_PARAMETER"
    }
  ]
}

The following contains a link to a resource that describes the protocols supported by the service.

{
  "errors": [
    {
      "properties": [
        "sourceFile.fileUrl"
      ],
      "text": "The URL provided does not represent a supported protocol",
      "resourceUrl": "https://api.ngpvan.com/support/supportedProtocols",
      "code": "UNSUPPORTED_PROTOCOL"
    }
  ]
}

The following contains a reference code to allow developers to communicate with NGP VAN staff about the error encountered.

{
  "errors": [
    {
      "properties": [
        "canvassResponses[1].VANID"
      ],
      "text": "You do not have access to the VANID", 
      "code": "INACCESSIBLE_VANID",
      "referenceCode": "ABC-123-DEF-456"
    }
  ]
}
Note:

Failed requests count against your overall API use quota. It’s recommended you employ an Exponential Backoff strategy for error handling.

Input Validation

Requests are validated to ensure data integrity and to guard against malicious code. Validation errors will be returned as standard Error objects with the code property set to INVALID_PARAMETER and HTTP status code to 400 Bad Request. Whenever possible, we will attempt to validate all properties of a request before returning validation results. In other words, we’ll tell you if both the firstName and lastName properties of a request are invalid rather than just firstName.

Some validation rules apply to all properties across all endpoints (unless specified otherwise). In particular, text properties are expected to not include HTML or HTML special character syntax. More precisely, input must not match this regular expression: [\<\>]+|&#. An example response for this type of error follows below.

{
  "errors": [
    {
      "properties": [
        "eventDescription"
      ],
      "text": "'eventDescription' must not contain invalid characters",
      "hint": "Value must not match the regular expression: [\<\>]+|&#",
      "code": "INVALID_PARAMETER"
    }
  ]
}

We use standard validation for email addresses. It’s not quite a regular expression.

We use standard phone number validation. It’s based on your contact’s country.

Expansion

By default, many API endpoints will only return first-order non-collection properties of a resource. These properties can be “expanded” by specifying valid expansion properties or sections in the $expand query parameter. This technique is used in both “list” endpoints and “get” endpoints.

If a collection property is not specified in an $expand parameter, the value of that property will be null. If a collection property is specified in an $expand parameter but that property has no values, that property will be an empty array.

Parameter Location Type Description
$expand query string A comma delimited list of expansion properties. Valid expansion properties are documented for each endpoint.

For example, consider a Person object that has name properties and collections of addresses, of emails, and of phone numbers.

GET /v4/people/432135

Returns the first-order properties (names) and null values for addresses, emails, and phones.

{
  "firstName": "Jim",
  "lastName": "Gordon",
  "addresses": null,
  "emails": null,
  "phones": null
}

Emails and phones can be requested by specifying emails and phones in the query string:

GET /v4/people/432135?$expand=emails,phones

Returns the first-order properties (names), populated emails and phones (even though the record has no phone numbers), and null value for addresses:

{
  "firstName": "Jim",
  "lastName": "Gordon",
  "addresses": null,
  "emails": [
    {
      "email": "jim@gotham.ci.us",
      "type": "Work",
      "isPreferred": false
    },
    {
      "email": "jim.gordon@batmail.com",
      "type": "Home",
      "isPreferred": true
    }
  ],
  "phones": []
}

Sending an $expand parameter to an endpoint that does not expand parameters will yield a 400 Bad Request error response:

{
  "errors": [
    {
      "code": "INVALID_PARAMETER",
      "text": "There are no valid expand sections for this endpoint, therefore '$expand' must be null",
      "properties": [
        "$expand"
      ]
    }
  ]
}

Sending an invalid $expand parameter to an endpoint also yields a 400 Bad Request error response. The supported properties are included in the hint of the error:

{
  "errors": [
    {
      "code": "INVALID_PARAMETER",
      "text": "'addresses' is not a valid argument for the '$expand' parameter",
      "properties": [
        "$expand"
      ],
      "hint": "The only valid expand section is: 'phones'"
    }
  ]
}

Pagination

Most API endpoints have “list” API methods that allow you to retrieve a large set of data (e.g., list Activist Codes, list Survey Questions, etc.). These endpoints share a common pattern for requests and responses.

Paginated endpoints accept the following optional parameters:

Parameter Location Type Description
$top query integer A limit on the number of records to return in a single request, similar to a page size. This can be a value between 1 and the maximum $top value for a particular endpoint, typically 200. If no $top value is specified, an endpoint’s default $top size is used, typically 50. If an endpoint has a default $top but no maximum $top, you can retrieve all values by sending the $top parameter with no values (e.g., resources?$top=). The maximum and default values are documented for each endpoint.
$skip query integer The number of records in a collection that should be skipped and not included in the result. If specified, must be greater than or equal to 0. For example, if you have a collection of 100 items and specify a $skip value of 10, the endpoint will return resources starting at 11.
$expand query string A comma delimited list of expansion properties (see Expansion)

Paginated endpoints share a common response format as well. The endpoints will return an object with the following properties:

Property Type Description
items array An array of zero or more endpoint specific objects (e.g., an Activist Code)
count integer Total number of items available at this endpoint using the filters specified. This can be greater than the number of items in the items array.
nextPageLink string An absolute URL at which additional records can be retrieved, if additional records are available. This will be the same as the request’s URL but with adjusted or appended $skip and $top values.

If no results are returned, an HTTP Status Code 200 OK is returned with the items array empty, count property equal to 0, and the nextPageLink null:

{
  "items": [],
  "nextPageLink": null,
  "count": 0
}

Endpoints

There are two primary endpoints for VAN API requests. Which endpoint you should use is determined by which VAN client with which you’re working.

https://api.securevan.com/v4
Used by all US-based clients and developer sandbox accounts
https://intlapi.securevan.com/v4
Used by most non-US clients

If you’re unsure which endpoint to use, contact NGP VAN API support.

People

Overview

People records are at the heart of VAN. Use this endpoint to interact with People in My Voters or My Campaign, and to create records in My Campaign.

Common Models

In order to ensure we are accurately matching to the one true person you are looking for in My Voters or My Campaign (or My Members or My Workers, where applicable), there are a few minimum combinations in order to trigger a match attempt. These include:

  • first name, last name, and email address
  • first name, last name, and phone
  • first name, last name, zip5, and date of birth
  • first name, last name, street number, street name, and zip5

Note that these are minimums - the more information you can provide about a contact, the better. If you fail to provide the minimum amount of required information, you will not get a match when attempting to find contacts, and will always create a new record when adding contacts.

Additionally, matching is accent sensitive in all databases (except the few that support French localization). This means that if matching relies on a last name, Pérez will not match Perez and vice versa. Matching is, however, case insensitive. PEREZ will match Perez.

All requests to “find” endpoints expect data to be structured like the following.

{
  "vanId": 1234,
  "firstName": "James",
  "middleName": "Worthington",
  "lastName": "Gordon",
  "dateOfBirth": "1976-07-04",
  "party": "D",
  "sex": "M",
  "salutation": "Dr. Gordon",
  "envelopeName": "Dr. Jim Gordon",
  "title": "Dr.",
  "suffix": "M.D.",
  "nickname": "Jim",
  "website": "www.jimgordon.com",
  "contactMethodPreferenceCode": "P",
  "employer": "Acme Medical Group",
  "occupation": "Physician",
  "emails": [
    {
      "email": "jim@gotham.city.us",
      "type": "P",
      "isPreferred": true,
      "isSubscribed": null
    },
    {
      "email": "jim@fake.ngpvan.com",
      "type": "W",
      "isPreferred": false,
      "isSubscribed": true
    },
  ],
  "phones": [
    {
      "phoneNumber": "1-555-888-9999",
      "phoneType": "H",
      "isPreferred": true,
      "phoneOptInStatus": "I"
    },
    {
      "phoneNumber": "1-555-555-1234",
      "phoneType": "W",
      "ext": 999,
      "isPreferred": false
    }
  ],
  "addresses": [
    {
      "addressId": 1234,
      "addressLine1": "123 Main St",
      "addressLine2": "Apt 3",
      "addressLine3": "c/o Jane Smith",
      "city": "Gotham City",
      "stateOrProvince": "IL",
      "zipOrPostalCode": "01234",
      "countryCode": "US",
      "type": "Voting",
      "isPreferred": true
    },
    {
      "addressId": 6789,
      "addressLine1": "555 Elm St",
      "addressLine2": "Suite 101",
      "addressLine3": "Marketing Department",
      "city": "Springfield",
      "stateOrProvince": "IL",
      "zipOrPostalCode": "01234",
      "countryCode": "US",
      "type": "Mailing",
      "isPreferred": false
    }
  ],
  "recordedAddresses": [
    {
      "addressId": 1234,
      "addressLine1": "123 Main St Apt 3",
      "city": "Gotham City",
      "stateOrProvince": "IL",
      "zipOrPostalCode": "01234",
      "countryCode": "US",
      "type": "Voting",
      "isPreferred": true
    },
    {
      "addressId": 6789,
      "addressLine1": "555 Elm St Suite 101",
      "city": "Springfield",
      "stateOrProvince": "IL",
      "zipOrPostalCode": "01234",
      "countryCode": "US",
      "type": "Mailing",
      "isPreferred": true
    },
    {
      "addressId": 888,
      "addressLine1": "987 Oak St",
      "city": "Gotham City",
      "stateOrProvince": "IL",
      "zipOrPostalCode": "01234",
      "countryCode": "US",
      "type": "Work",
      "isPreferred": true
    },
    {
      "addressId": 887,
      "addressLine1": "987 Maple St",
      "city": "Gotham City",
      "stateOrProvince": "IL",
      "zipOrPostalCode": "01234",
      "countryCode": "US",
      "type": "Work",
      "isPreferred": false
    },
    {
      "addressId": 999,
      "addressLine1": "2233 Ash St",
      "city": "Springfield",
      "stateOrProvince": "IL",
      "zipOrPostalCode": "01234",
      "countryCode": "US",
      "type": "Custom",
      "isPreferred": true
    }
  ],
  "identifiers": [
    {
      "type": "bsdid",
      "externalId": "746313"
    }
  ],
  "customFieldValues": [
    {
      "customFieldId": 500,
      "customFieldGroupId": 100,
      "assignedValue": "someValue"
    }
  ],
  "selfReportedRace": {
    "reportedRaceId": 4
  },
  "selfReportedEthnicity": {
    "reportedEthnicityId": 5
  },
  "selfReportedLanguagePreference": {
    "reportedLanguagePreferenceId": 6
  },
  "suppressions": [
    {
      "suppressionCode": "NW",
      "suppressionName": "Do not walk"
    },
    {
      "suppressionCode": "NE",
      "suppressionName": "Do not email"
    }
  ]
}
Person
Property Type Max length Description
vanId string n/a Optional; the MyCampaignID of the MyCampaign record (if operating in MyCampaign mode) or the VoterFile VANID of the VoterFile record (if operating in VoterFile mode) - if the ID is known in advance.
firstName string 20 Optional; a person’s first name
middleName string 20 Optional; a person’s middle name
lastName string 25 Optional; a person’s last name
dateOfBirth datetime n/a Optional; a person’s date of birth, ISO 8601 formatted, and must be in the 20th or 21st century
party string 1 Optional; a one-character string indicating party affiliation, e.g. “D”
sex string 1 Optional; a one-chracter string indicating sex, must be “M” or “F”
salutation string 20 Optional; preferred greeting for correspondence
envelopeName string 60 Optional; preferred name to use for mailings
title string 10 Optional; an honorific
suffix string 50 Optional; part of name following last name, e.g. “Jr.”
nickname string 50 Optional; preferred informal name
website string 50 Optional; personal website
contactMethodPreference string 1 Optional. Indicates the method by which this person prefers contact. Must be one of: P → phone, E → email, M → mail, F → fax, S → SMS.
employer string 50 Optional; name of the organization where the person works, e.g. “Kennedy High School”. May not be available in every context.
occupation string 50 Optional; nature of the person’s work, e.g. “teacher”. May not be available in every context.
emails array n/a Optional; an array of email objects
phones array n/a Optional; an array of phone objects
addresses array n/a Optional; an array of address objects. Will contain only the best Home address and best Mailing address, if available.
recordedAddresses array n/a Read-only; an array of address objects indicating all known addresses
identifiers array n/a Optional; an array of identifier objects
customFieldValues array n/a Optional; an array of customFieldValue objects
selfReportedRace object n/a Optional; indicates the person’s race. The reportedRaceId must match one of the reported races available in the current context.
selfReportedEthnicity object n/a Optional; indicates the person’s ethnicity. The reportedEthnicityId must match one of the reported ethnicities available in the current context.
selfReportedLanguagePreference object n/a Optional; indicates the person’s language preference. The reportedLanguagePreferenceId must match one of the reported language preferences available in the current context.
suppressions array n/a Read-only; an array of suppression objects indicating that the person should not receive communications. Suppressions may not be applied directly, but may be applied as a result of canvass responses (e.g., a canvass result of “Do not call” will trigger a corresponding suppression), or may be applied directly by users in the front end.
Email
Property Type Description
email string Required; a valid email address
type string Optional; one of: P → personal, W → work, O → other. Default, if not supplied, is P.
isPreferred bool Optional; an indicator of whether the email address is the person’s preferred address; defaults to false
isSubscribed bool Optional; indicates whether the email address may be used in a broadcast email. Must be explicitly set to true for the email address to opt-in to receive mass email. If it’s explicitly set to false, it is treated as an opt-out and you will not be able to resubscribe the email address. If you are unsure of the subscription status of the email, leave this property null.
Phone
Property Type Description
phoneNumber string Required; after removing all non-numeric characters, the number is evaluated using the target context’s country specific validation.
phoneType string Optional; one of: H → home, W → work, C → cell (alias for mobile), M → mobile, F → fax
ext string Optional; no more than six numeric characters
isPreferred bool Optional; an indicator of whether the phone number is the person’s preferred phone number; defaults to false
phoneOptInStatus string Optional; one of: I → opt in, U → unknown, O → opt out. Default, if not supplied, is U
Address
Property Type Description
addressId int Read-only; unique identifier of the address on this person
addressLine1 string Optional; indicates first line of a street address when used in the POST /people/findOrCreate. In the GET method, indicates the result of concatenating all three address lines and standardizing the resulting street address.
addressLine2 string Optional; second line of a street address
addressLine3 string Optional; third line of a street address
city string Optional; city or town
stateOrProvince string Optional; two or three character State or Province code (e.g., MN, ON, NSW, etc.)
zipOrPostalCode string Optional; ZIP, ZIP+4, Postal Code, Post code, etc.
countryCode string Optional; a two character ISO country code that is supported by your VAN context
type string Optional; one of: Mailing, Home, Voting, Work, Custom; some types may not be available in certain contexts. Note that Home and Voting have identical meaning. If a mailing address has not been provided for a contact, then the home address for that contact will also be used as the contact’s mailing address.
isPreferred bool Read-only; indicates whether this address is the best known address of the indicated type. The best known address is the most recently-updated address of a given address type.
Identifier

Used for known external identifiers (e.g., DWID, Voter File ID, etc.). External IDs in VAN are case-insensitive. Abcd1234 will always match ABCD1234.

Property Type Description
type string Required; a known external identifier that is available in the current context. Use votervanid for VoterFile VANID if making a MyCampaign call. Use dwid for Catalist DWIDs in either VoterFile or MyCampaign mode.
externalId string Required; case-insensitive
CustomFieldValue
Property Type Description
customFieldId int Required; a known custom field identifier that is available in the current context.
customFieldGroupId int Required; a known custom field group identifier that identifies the Custom Field Group to which this Custom Field belongs, and that is available in the current context.
assignedValue string The value to be applied to the Custom Field. The value must be consistent with the type of the Custom Field
Suppression
Property Type Description
suppressionCode string Short code which identifies the suppression, e.g. “NC”
suppressionName string Full explanation of the suppression, e.g. “Do not call”

The various find endpoints return a common response object.

{
  "vanId": 1264324,
  "status": "UnmatchedStored"
}

vanId may be null if no match is found and a store is not requested.

The HTTP status code is set per status value.

Status HTTP Code Description
Matched 302 Found A match was found (and updated, if relevant) and the Location header is set
Stored 201 Created Not implemented
Unmatched 404 Not Found No match was found
UnmatchedStored 201 Created No match was found, but a new record was created (and the Location header is set)
Processed 204 No Content Not implemented
UnmatchedProcessed 204 No Content Not implemented

POST/people/find

Look for a matched record.
Description

Attempts to find a person using the given match candidate.

Response

Match Response

POST/people/findOrCreate

Look for a matched record, create one if none exists
Description

Attempts to find the given match candidate. If a person is found, it is updated with the information provided. If a person is not found, a new person record is created.

Response

Match Response

GET/people/{vanId}

Retrieve a person by vanId.
Description

Retrieve a person record and associated contact information

Request
Parameter Location Type Description
vanId route integer Unique person identifier available in the current context
$expand query string Optional; comma delimited list of expansion properties: phones, emails, addresses, customFields, externalIds, recordedAddresses, preferences, suppressions, reportedDemographics
GET /people/215501?$expand=phones,emails,addresses,customFields,externalIds,recordedAddresses,preferences,suppressions,reportedDemographics

Note the following with regards to $expand parameters:

  • The addresses parameter will provide best known Home and Mailing address, if available.
  • The recordedAddresses parameter will provide all available address history, but requires special permissions.
  • The preferences parameter is required to retrieve the following properties: nickname, website, and contactMethodPreferenceCode.
Response

If a result is found, it will look like:

{
  "vanId": 215501,
  "firstName": "James",
  "lastName": "Gordon",
  "middleName": null,
  "dateOfBirth": "1920-07-04",
  "emails": [
    {
      "type": null,
      "email": "jim@gotham.city.us",
      "dateCreated": "2004-10-31T14:35:00Z",
      "isPreferred": true
    }
  ],
  "phones": [
    {
      "phoneNumber": "6175555920",
      "ext": "5125",
      "dateCreated": "2013-10-25T12:23:00Z",
      "phoneType": "Work",
      "isPreferred": false,
      "phoneOptInStatus": "Opt In"
    },
    {
      "phoneNumber": "7815550256",
      "ext": null,
      "dateCreated": "2013-10-25T12:23:00Z",
      "phoneType": "Cell",
      "isPreferred": true,
      "phoneOptInStatus": "Unknown"
    }
  ],
  "addresses": [
    {
      "addressId": null,
      "addressLine1": "3001 Tradewinds Trl",
      "addressLine2": null,
      "addressLine3": null,
      "city": "Orlando",
      "stateOrProvince": "FL",
      "zipOrPostalCode": "32805",
      "geoLocation": null,
      "countryCode": null,
      "preview": "3001 Tradewinds Trl",
      "type": "Voting",
      "isPreferred": null
    },
    {
      "addressId": null,
      "addressLine1": "320 College Ave",
      "addressLine2": null,
      "addressLine3": null,
      "city": "Somerville",
      "stateOrProvince": "MA",
      "zipOrPostalCode": "02145",
      "geoLocation": null,
      "countryCode": null,
      "preview": "320 College Ave ",
      "type": "Mailing",
      "isPreferred": null
    }
  ],
  "identifiers": [
    {
      "type": "MembershipID",
      "externalId": "999313123"
    }
  ],
  "customFieldValues": [
    {
      "customField": { },
      "assignedValue": "true"
    },
    {
      "customField": { },
      "assignedValue": "100.00"
    }
  ]
}

If the specified vanId can’t be found, an error will be returned with a 404.

{
  "errors": [
    {
      "code": "NOT_FOUND",
      "text": "The specified resource cannot be found."
    }
  ]
}

If the specified vanId is not accessible in the current context (e.g., the associated user does not have access to the person), an error will be returned with a 403.

{
  "errors": [
    {
      "code": "FORBIDDEN",
      "text": "Access to this resource is restricted."
    }
  ]
}

GET/people/{personIdType}:{personId}

Retrieve a person by a case-insensitive external ID.
Description

Retrieve a person record and associated contact information. For example /people/DWID:12345 would retrieve a person whose DWID is 12345.

Request
Parameter Location Type Description
personIdType route string Required; a known person identifier type available in the current context
personId route string Required; an external identifier, URL encoded
$expand query string Optional; comma delimited list of expansion properties: phones, emails, addresses, customFields
GET /people/dwid:98877325?$expand=phones,emails,addresses,customFields
Response

If a result is found, it will look like:

{
  "vanId": 215501,
  "firstName": "James",
  "lastName": "Gordon",
  "middleName": null,
  "dateOfBirth": "1920-07-04",
  "emails": [
    {
      "type": null,
      "email": "jim@gotham.city.us",
      "dateCreated": "2004-10-31T14:35:00Z",
      "isPreferred": true
    }
  ],
  "phones": [
    {
      "phoneNumber": "6175555920",
      "ext": "5125",
      "dateCreated": "2013-10-25T12:23:00Z",
      "phoneType": "Work",
      "isPreferred": false,
      "phoneOptInStatus": "Opt In"
    },
    {
      "phoneNumber": "7815550256",
      "ext": null,
      "dateCreated": "2013-10-25T12:23:00Z",
      "phoneType": "Cell",
      "isPreferred": true,
      "phoneOptInStatus": "Unknown"
    }
  ],
  "addresses": [
    {
      "addressId": null,
      "addressLine1": "3001 Tradewinds Trl",
      "addressLine2": null,
      "addressLine3": null,
      "city": "Orlando",
      "stateOrProvince": "FL",
      "zipOrPostalCode": "32805",
      "geoLocation": null,
      "countryCode": null,
      "preview": "3001 Tradewinds Trl",
      "type": "Voting",
      "isPreferred": null
    },
    {
      "addressId": null,
      "addressLine1": "320 College Ave",
      "addressLine2": null,
      "addressLine3": null,
      "city": "Somerville",
      "stateOrProvince": "MA",
      "zipOrPostalCode": "02145",
      "geoLocation": null,
      "countryCode": null,
      "preview": "320 College Ave ",
      "type": "Mailing",
      "isPreferred": null
    }
  ],
  "identifiers": [
    {
      "type": "MembershipID",
      "externalId": "999313123"
    }
  ],
  "customFieldValues": [
    {
      "customField": { },
      "assignedValue": "true"
    },
    {
      "customField": { },
      "assignedValue": "100.00"
    }
  ]
}

If the specified vanId can’t be found, an error will be returned with a 404.

{
  "errors": [
    {
      "code": "NOT_FOUND",
      "text": "The specified resource cannot be found."
    }
  ]
}

If the specified vanId is not accessible in the current context (e.g., the associated user does not have access to the person), an error will be returned with a 403.

{
  "errors": [
    {
      "code": "FORBIDDEN",
      "text": "Access to this resource is restricted."
    }
  ]
}

POST/people/{vanId}/canvassResponses

Add Canvass Responses to a person
Description

A Canvass Response encapsulates a complete interaction with a person: it may have a Result Code (if the person was unavailable) or it may have an array of responses such as Activist Codes, Survey Questions, and other Script elements. Optionally, additional information about the canvass interaction can be specified using the canvassContext property such as the date of the contact attempt (dateCanvassed) or the Contact Type (contactTypeId). Use this endpoint to record these interactions.

Request

A Canvass Response is expected to be structured like the following:

{
  "canvassContext": {
    "contactTypeId": 2,
    "inputTypeId": 14,
    "dateCanvassed": "2012-04-09T00:00:00-04:00"
  },
  "resultCodeId": null,
  "responses": [
    {
      "activistCodeId": 18917,
      "action": "Apply",
      "type": "ActivistCode"
    },
    {
      "volunteerActivityId": 3425,
      "action": "Apply",
      "type": "VolunteerActivity"
    },
    {
      "surveyQuestionId": 109149,
      "surveyResponseId": 465468,
      "type": "SurveyResponse"
    }
  ]
}
Canvass Response
Property Type Description
canvassContext object Optional; describes the context in which this Canvass Response was created
resultCodeId int Optional; specifies the Result Code of this Response. If no resultCodeId is specified, responses must be specified. Conversely, if responses are specified, resultCodeId must be null (a result of Canvassed is implied). The resultCodeId must be a valid Result Code in the current context.
responses array Optional; an array of Script Responses. If specified, resultCodeId must be null.
Canvass Context
Property Type Description
contactTypeId int Optional; a valid Contact Type ID
inputTypeId int Optional; a valid Input Type ID (defaults to 11API)
dateCanvassed datetime Optional; the ISO 8601 formatted date that the canvass attempt was made (defaults to today’s date)
Script Responses

Each Script Response has a property that determine’s the response’s type—currently one of ActivistCode, SurveyResponse, and VolunteerActivity.

Activist Codes
Property Type Description
type string ActivistCode
activistCodeId int Required; a valid Activist Code ID
action string Optional; Apply (default) or Remove to indicate whether to apply or remove an Activist Code from a person
Survey Responses
Property Type Description
type string SurveyResponse
surveyQuestionId int Required; a valid Survey Question ID
surveyResponseId int Required; a valid Response to the specified surveyQuestionId
Volunteer Activities
Property Type Description
type string VolunteerActivity
volunteerActivityId int Optional; a valid Volunteer Activity ID
action string Optional; Apply (default) or Remove to indicate whether to apply or remove a Volunteer Activity from a person
Response

HTTP Status Code 204 No Content is returned.

POST/people/{personIdType}:{personId}/canvassResponses

Add Canvass Responses to a person by a case-insensitive external ID.
Description

This endpoint is the same as people/{vanId}/canvassResponses but uses external IDs rather than VANIDs.

Response

HTTP Status Code 204 No Content is returned.

POST/people/{vanId}/codes

Apply a Code to a Person
Description

Use this endpoint to apply a single Code to a Person.

Request
Property Type Description
codeId int Required; Unique identifier for an existing Code that is applicable to a Person.
POST /people/123123/codes
{
  "codeId": 123456
}
Response

If the specified Person does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If the specified Person does exist but the Code does not or cannot be applied to People, this endpoint will return an error with HTTP Status Code 400 Bad Request.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

POST/people/{personIdType}:{personId}/codes

Apply a Code to a Person identified by a case-insensitive external ID
Description

This endpoint is the same as people/{vanId}/codes but uses external IDs rather than VANIDs.

Request

See people/{vanId}/codes.

Response

If the specified Person does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If the specified Person does exist but the Code does not or cannot be applied to People, this endpoint will return an error with HTTP Status Code 400 Bad Request.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

DELETE/people/{vanId}/codes/{codeId}

Remove a specific Code from a Person
Description

Use this endpoint to remove a single Code from a Person.

Request
Parameter Location Type Description
vanId route integer Unique person identifier available in the current context
codeId route integer Required; the ID of a Code that may or may not be applied to the person
DELETE /people/123431/codes/1233

This request has no body.

Response

If the specified Person does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

DELETE/people/{personIdType}:{personId}/codes/{codeId}

Remove a specific Code from a Person identified by a case-insensitive external ID
Description

This endpoint is the same as people/{vanId}/codes but uses external IDs rather than VANIDs.

Request

See people/{vanId}/codes.

Response

If the specified Person does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

PUT/people/{vanId}/myActivistFlags

Apply the My Activist flag to a person.
Description

Marks this person, who belongs to a master data sharing committee, as an activist who can be viewed in the current context.

Request

Empty request

Response

HTTP Status Code 200 OK is returned.

DELETE/people/{vanId}/myActivistFlags

Remove the My Activist flag from a person.
Description

Prevents this person, who belongs to a master data sharing committee, from being be viewed in the current context as an activist.

Request

Empty request

Response

HTTP Status Code 200 OK is returned.

Canvass Responses

Overview

VAN is a great tool for tracking interaction with People. Often this interaction is represented as “canvass responses,” or the result of a canvassing interaction. Use this endpoint to retrieve metadata around the canvassing infrastructure.

GET/canvassResponses/contactTypes

Retrieve available Contact Types
Description

Contact Types are different ways a canvass response was collected. For example, responses collected while walking around your neighborhood would have a Contact Type of Walk. While most Contact Types are common across VAN instances, some instances may have custom Contact Types. Use this endpoint to retrieve all available Contact Types. Additionally, Contact Types can be assigned to specific Input Types. For example, a Contact Type of Walk wouldn’t make sense for an Input Type of Virtual Phone Bank. To return Input Type appropriate Contact Types, use the optional inputTypeId parameter.

Request
Parameter Location Type Description
inputTypeId query int Optional; filter Contact Types to those available to the given Input Type
GET /canvassResponses/contactTypes?inputTypeId=11
Response
[
  {
    "contactTypeId": 1,
    "name": "Phone"
  },
  {
    "contactTypeId": 2,
    "name": "Walk"
  }
]

GET/canvassResponses/inputTypes

Retrieve available Input Types
Description

Input Types are different ways canvass responses are entered into VAN. For example, responses entered via Bulk Upload will use the Input Type of Bulk. By default, responses entered via the API will use an Input Type of API. While most Input Types are common across VAN instances, some instances may have custom Input Types. Use this endpoint to retrieve all available Input Types.

Request
GET /canvassResponses/inputTypes
Response
[
  {
    "inputTypeId": 11,
    "name": "API"
  },
  {
    "inputTypeId": 4,
    "name": "Bulk"
  },
  {
    "inputTypeId": 2,
    "name": "Manual"
  },
  {
    "inputTypeId": 14,
    "name": "Mobile"
  },
  {
    "inputTypeId": 10,
    "name": "VPB"
  },
  {
    "inputTypeId": 23,
    "name": "Website"
  }
]

GET/canvassResponses/resultCodes

Retrieve available Result Codes
Description

Result Codes, or contact dispositions, are the result of a contact attempt. For example, Not Home, Wrong Number, Moved, etc. A successful contact interaction yields a Result Code called Canvassed which is automatically applied when canvass responses are submitted (e.g., when a Survey Response is recorded). Unsuccessful contact attempts are what Result Codes are all about. This endpoint returns a list of those response codes available in the current context. Similar to Contact Types, Result Codes’ availability can vary by Input Type and/or Contact Type. For example, Wrong Number only makes sense in the context of a Call Contact Type. Moved only makes sense in the context of a Walk Contact Type.

Note:

The application of some Result Codes triggers additional actions. For example, if you record a Wrong Number result, the person’s phone number is marked “bad.”

Request
Parameter Location Type Description
inputTypeId query int Optional; filter Result Codes to those available to the given Input Type
contactTypeId query int Optional; filter Result Codes to those available to the given Contact Type
GET /canvassResponses/resultCodes?contactTypeId=1
Response
[
  {
    "resultCodeId": 18,
    "name": "Busy",
    "mediumName": "Busy",
    "shortName": "BZ"
  },
  {
    "resultCodeId": 25,
    "name": "Disconnected",
    "mediumName": "Disc",
    "shortName": "WX"
  },
  {
    "resultCodeId": 19,
    "name": "Left Message",
    "mediumName": "LM",
    "shortName": "LM"
  },
  {
    "resultCodeId": 20,
    "name": "Wrong Number",
    "mediumName": "Wr#",
    "shortName": "WN"
  }
]

Activist Codes

Overview

An Activist Code is a tag used to identify someone’s affiliations, activities, or interests that can also tell you the direction and strength of their political views. Examples are members of PETA, union members, campaign volunteers, party officials, or signers of a petition. An Activist Code is essentially a “yes” answer to a question. In other words, you really don’t care who is not a union member or does not want a yard sign, but you frequently may want to search on records that meet those criteria. Use this endpoint to retrieve information about all available Activist Codes.

Activist Codes can be applied to people by applying canvass responses.

Common Models

{
  "activistCodeId": 3202,
  "type": "Visibility",
  "name": "Yard Sign",
  "mediumName": "Yard sign",
  "shortName": "YS",
  "description": "Voter requested yard sign",
  "scriptQuestion": "Would you be interested in having a yard sign in support of Democratic candidates?",
  "status": "Active"
}
Property Type Description
activistCodeId int Unique identifier for an Activist Code in this context (this is an ID that is often unique across many VAN database tabs)
type string A general category for an Activist Code
name string A name for the Activist Code, no longer than 20 characters
mediumName string A shorter name for the Activist Code, no longer than 9 characters
shortName string An even shorter name for the Activist Code, no longer than 3 characters
description string A description of this Activist Code
scriptQuestion string If the Activist Code is to appear on a Script, this is the question that would appear on the script
status string For organizational purposes, users often use various statuses to hide older Activist Codes. This property will be one of: Active, Archived, or Inactive.

GET/activistCodes

Retrieve available Activist Codes
Description

Use this endpoint to retrieve all Activist Codes that are available in the current context.

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

By default, this endpoint returns 50 records per request. A maximum of 200 records per request is allowed via the $top parameter.

Parameter Location Type Description
statuses query string Comma delimited list of statuses of Activist Codes. One or more of Active (default), Archived, and Inactive.
name query string Filters to Activist Codes with names that start with the given input
type query string Filters to Activist Codes of the given type
GET /activistCodes?statuses=Active,Archived&type=Volunteer
Response

This endpoint responds with a standard paged response of Activist Codes.

{
  "items": [
    {
      "activistCodeId": 3214,
      "type": "Volunteer",
      "name": "Precinct Captain",
      "mediumName": "P Capt",
      "shortName": "PC",
      "description": "Precinct Captain",
      "scriptQuestion": "Would you be willing to be a Precinct Captain?",
      "status": "Active"
    },
    {
      "activistCodeId": 8009,
      "type": "Volunteer",
      "name": "Stand Out",
      "mediumName": "Stand Out",
      "shortName": "SO",
      "description": null,
      "scriptQuestion": null,
      "status": "Archived"
    },
    {
      "activistCodeId": 36222,
      "type": "Volunteer",
      "name": "Supporter",
      "mediumName": "Supporter",
      "shortName": "Sup",
      "description": null,
      "scriptQuestion": null,
      "status": "Active"
    }
  ],
  "nextPageLink": null,
  "count": 3
}

GET/activistCodes/{activistCodeId}

Retrieve a specific Activist Code
Description

Use this endpoint to retrieve information about a specific Activist Code available in the current context.

Request

This endpoint accepts standard list parameters, returns a standard paged response, and takes the following optional filter parameters:

Parameter Location Type Description
activistCodeId route int or string Unique identifier for a specific Activist Code. This is either an integer or a VAN encoded identifier (e.g., EID28CG).
GET /activistCodes/3202
Response

A standard Activist Code object, if found.

Survey Questions

Overview

Survey Questions are at the heart of interactions with people. Survey Questions have a set of possible Survey Responses. For example, the question “If the election were held today, for whom would you vote?” may have a set of responses including “Supports my candidate,” “Undecided,” and “Supports my opponent.” Use this endpoint to retrieve information about all available Survey Questions and Responses.

Survey Question Responses can be applied to people by applying canvass responses.

Common Models

{
  "surveyQuestionId": 54949,
  "type": "Candidate",
  "cycle": 2010,
  "name": "Maddow for Senate",
  "mediumName": "Maddow",
  "shortName": "MS",
  "scriptQuestion": "In the upcoming race for US Senate, do you plan to vote for Republican Scott Brown or Democrat Rachel Maddow?",
  "status": "Active",
  "responses": [
    {
      "surveyResponseId": 246016,
      "name": "1 - Strong Maddow",
      "mediumName": "1",
      "shortName": "1"
    },
    {
      "surveyResponseId": 246017,
      "name": "2 - Leaning Maddow",
      "mediumName": "2",
      "shortName": "2"
    },
    {
      "surveyResponseId": 246018,
      "name": "3 - Undecided",
      "mediumName": "3",
      "shortName": "3"
    },
    {
      "surveyResponseId": 246020,
      "name": "4 - Leaning Brown",
      "mediumName": "4",
      "shortName": "4"
    },
    {
      "surveyResponseId": 246019,
      "name": "5 - Strong Brown",
      "mediumName": "5",
      "shortName": "5"
    }
  ]
}

Each Survey Question has the following properties:

Property Type Description
surveyQuestionId int Unique identifier for a Survey Question in this context (this is an ID that is often unique across many VAN database tabs)
type string A general category for a Survey Question (e.g., Candidate, Issue, etc.)
cycle int The election cycle or year this question is assigned
name string A name for the Survey Question, no longer than 20 characters
mediumName string A shorter name for the Survey Question, no longer than 9 characters
shortName string An even shorter name for the Survey Question, no longer than 4 characters
scriptQuestion string The text of the actual question that would appear on a script
status string For organizational purposes, VAN users often use various statuses to hide older Survey Questions. This property will be one of: Active, Archived, or Inactive.
responses array An array of zero or more Survey Response objects, sorted as they should appear on a script

Each Survey Response has the following properties:

Property Type Description
surveyResponseId int An identifier (unique to this Survey Question) for a Survey Response
name string A name for the Survey Question, no longer than 20 characters
mediumName string A shorter name for the Survey Question, no longer than 3 characters
shortName string An even shorter name for the Survey Question, no longer than 1 character

GET/surveyQuestions

Retrieve available Survey Questions
Description

Use this endpoint to retrieve all Survey Questions that are available in the current context.

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

By default, this endpoint returns 50 records per request. A maximum of 200 records per request is allowed via the $top parameter.

A Survey Question’s Response collection is automatically populated without specifying an $expand parameter.

The endpoint takes the following optional filter parameters:

Parameter Location Type Description
statuses query string Comma delimited list of statuses of Survey Questions. One or more of Active (default), Archived, and Inactive.
name query string Filters to Survey Questions with names that start with the given input
type query string Filters to Survey Questions of the given type
question query string Filters to Survey Questions with script questions that contain the given input
cycle query int A year in the format YYYY; filters to Survey Questions with the given cycle
GET /surveyQuestions?statuses=Active,Archived&cycle=2010&type=Candidate
Response

This endpoint responds with a standard paged response of Survey Questions.

{
  "items": [
    {
      "surveyQuestionId": 54945,
      "type": "Candidate",
      "cycle": 2010,
      "name": "John Kerry senate",
      "mediumName": "Kerry",
      "shortName": "Kerr",
      "scriptQuestion": "Will you vote for John Kerry in the upcoming Senate race?",
      "status": "Archived",
      "responses": [
        {
          "surveyResponseId": 245998,
          "name": "1 Strong Kerry",
          "mediumName": "1",
          "shortName": "K"
        },
        {
          "surveyResponseId": 245999,
          "name": "2 Leaning Kerry",
          "mediumName": "2",
          "shortName": "k"
        },
        {
          "surveyResponseId": 246000,
          "name": "3 Undecided",
          "mediumName": "3",
          "shortName": "U"
        },
        {
          "surveyResponseId": 246002,
          "name": "4 Leaning Republican",
          "mediumName": "5 L",
          "shortName": "r"
        },
        {
          "surveyResponseId": 246001,
          "name": "5 Strong Republican",
          "mediumName": "4",
          "shortName": "R"
        },
        {
          "surveyResponseId": 403566,
          "name": "6 Green Party",
          "mediumName": "6 G",
          "shortName": "G"
        },
        {
          "surveyResponseId": 408826,
          "name": "7 Libertarian",
          "mediumName": "7 L",
          "shortName": "L"
        }
      ]
    },
    {
      "surveyQuestionId": 54949,
      "type": "Candidate",
      "cycle": 2010,
      "name": "Maddow for Senate",
      "mediumName": "Maddow",
      "shortName": "MS",
      "scriptQuestion": "In the upcoming race for US Senate, do you plan to vote for Republican Scott Brown or Democrat Rachel Maddow?",
      "status": "Active",
      "responses": [
        {
          "surveyResponseId": 246016,
          "name": "1 - Strong Maddow",
          "mediumName": "1",
          "shortName": "1"
        },
        {
          "surveyResponseId": 246017,
          "name": "2 - Leaning Maddow",
          "mediumName": "2",
          "shortName": "2"
        },
        {
          "surveyResponseId": 246018,
          "name": "3 - Undecided",
          "mediumName": "3",
          "shortName": "3"
        },
        {
          "surveyResponseId": 246020,
          "name": "4 - Leaning Brown",
          "mediumName": "4",
          "shortName": "4"
        },
        {
          "surveyResponseId": 246019,
          "name": "5 - Strong Brown",
          "mediumName": "5",
          "shortName": "5"
        }
      ]
    }
  ],
  "nextPageLink": null,
  "count": 2
}

GET/surveyQuestions/{surveyQuestionId}

Retrieve a specific Survey Question
Description

Use this endpoint to retrieve information about a specific Survey Question (and its set of Survey Responses) available in the current context.

Request

This endpoint takes the following parameter:

Parameter Location Type Description
surveyQuestionId route int or string Unique identifier for a specific Survey Question. This is either an integer or a VAN encoded identifier (e.g., EID28CG).
GET /surveyQuestions/54949
Response

A standard Survey Question object, if found.

Codes

Overview

Codes are used as hierarchical categorization system in VAN (and are not to be confused with Activist Codes). Like Activist Codes, they are a “yes” answer to a question, but because they provide hierarchy, they’re able to answer more than a single “yes” question. For example, you could categorize constituent groups in a hierarchical manner:

  • Constituencies
    • Elected Officials
      • Federal
        • Representative
        • Senator
      • Municipal
        • City Councilor
        • County Commissioner
        • Mayor
      • State
        • Governor
        • State Representative
        • State Senator
    • Faith Community
      • Catholic Americans
      • Jewish Americans
    • Labor
      • AFL-CIO
      • SEIU
      • Teamsters
    • Seniors and Retirees
    • Youth
      • College Democrats
      • Young Democrats

If the “SEIU” Code is applied, it answers “yes” to three questions: first, Is this a Constituency?, second, Is this a Labor Constituency?, and third, Is this an SEIU Labor Constituency?. This allows a single Code to carry a significant amount of information because each Code can have a parent. (e.g., the parent of College Democrats is Youth) As is demonstrated in the above example, Codes need not have the same number of parents, grand-parents, etc. “Mayor” is three levels deep whereas “Seniors and Retirees” is only one level deep.

Codes can have another helpful attribute called applicability. In some cases, a Code’s parent may be able to stand on its own. For example, if “Catholic Americans” is too specific of an attribute, Faith Community may suffice. In this case, it’d make sense to allow “Faith Community” to be Applicable. In the case of “Elected Officials,” you may decide that your classifications are complete enough that you do not want to simply classify something as “State.” In that case, you’d make “State” be Searchable Only. This means that you can find things tagged with any State Elected Official but no thing can be just a State Elected Official in and of itself.

Last but not least, the same Code, unlike Activist Codes, can be applied to a number of different entities in VAN: Events, Locations, Organizations, People, etc. (NB: not all APIs have Code support yet.) This notion is a Code’s Supported Entities. Each entity can have different applicability rules. For example, if you’re using the above Constituency Codes to classify Organizations, you may only be interested in organizations of Elected Officials at the Federal, Municipal, and State levels and nothing more specific.

Use the Codes endpoint to create, update, and delete Codes, as well as to discover existing Codes and retrieve meta data about each.

Codes are applied using each supported entity’s endpoint.

Common Models

The following is an example of a Labor Code which is applicable to Events but not to Locations. (To search for a Location searchable with a Labor Code, you’d create a child of this Code that is applicable.) This Code’s parent has parentCodeId which, in this example, is a Code called Constituencies.

{
  "codeId": 20515,
  "parentCodeId": 20513,
  "name": "Labor",
  "description": "This is a description of Labor.",
  "dateCreated": "2015-04-05T12:59:00Z",
  "supportedEntities": [
    {
      "name": "Events",
      "isSearchable": true,
      "isApplicable": true
    },
    {
      "name": "Locations",
      "isSearchable": true,
      "isApplicable": false
    }
  ]
}
Code

Each Code has the following properties:

Property Type Description
codeId int Read-only; Unique identifier for a Code in this context
parentCodeId int Optional; a unique identifier for this Code’s parent
name string A name for this Code, no longer than 50 characters and is not guaranteed to be unique. In addition to the standard text input validation rules, names must not include slashes or backslashes. More precisely, it must not match this regular expression: [\/\\]+
description string Read-only; A description for this Code, no longer than 200 characters and may be null.
dateCreated datetime Read-only; The date and time this Code was created
supportedEntities array Optional; An array of zero or more Supported Entity objects that enumerate the searchability and applicability rules of this Code
Supported Entity
Property Type Description
name string Required; A name of a valid Supported Entity type available in this context
isSearchable bool Required; Indicates that this Code is searchable. This should always be true.
isApplicable bool Optional; Indicates that this Code can be applied to entities of type name

GET/codes/supportedEntities

Retrieve Code Supported Entities
Description

Use this endpoint to retrieve all Entity types that Codes can be associated with in this context. Code support varies by context, but is often one of:

  • ActivistCodes — Codes can be applied to Activist Codes in the VAN UI
  • Contacts — Contacts are synonymous with People
  • Events — Codes can be applied to Events
  • Locations — Codes can be applied to Locations
  • Organizations — Codes can be applied to Organizations
  • SurveyQuestions — Codes can be applied to Survey Questions in the VAN UI
Request

This endpoint takes no parameters.

GET /codes/supportedEntities
Response

This endpoint returns an array of strings of Entity types:

[
  "Contacts",
  "Events",
  "Locations"
]

GET/codes

Find Codes
Description

Use this endpoint to find Codes available in the current context using a number of filter options.

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

By default, this endpoint returns 50 records per request. A maximum of 200 records per request is allowed via the $top parameter.

The only valid expansion property is: supportedEntities.

The endpoint takes the following optional filter parameters:

Parameter Location Type Description
supportedEntities query string Filters to Codes that are searchable or applicable to this comma separated list of Entities
name query string Filters to Codes with names that contain the given input
parentCodeId query int Filters to Codes that are direct children of the given Code ID
GET /codes?parentCodeId=20513&$expand=supportedEntities&$top=3
Response

This endpoint responds with a standard paged response of Codes.

{
  "items": [
    {
      "codeId": 20514,
      "parentCodeId": 20513,
      "name": "LGBT",
      "dateCreated": "2015-04-05T12:59:00Z",
      "supportedEntities": [
        {
          "name": "Events",
          "isSearchable": true,
          "isApplicable": true
        }
      ]
    },
    {
      "codeId": 20515,
      "parentCodeId": 20513,
      "name": "Labor",
      "dateCreated": "2015-04-05T12:59:00Z",
      "supportedEntities": [
        {
          "name": "Organizations",
          "isSearchable": true,
          "isApplicable": false
        },
        {
          "name": "Events",
          "isSearchable": true,
          "isApplicable": true
        },
        {
          "name": "Locations",
          "isSearchable": true,
          "isApplicable": false
        }
      ]
    },
    {
      "codeId": 20516,
      "parentCodeId": 20513,
      "name": "Seniors",
      "dateCreated": "2015-04-05T13:00:00Z",
      "supportedEntities": [
        {
          "name": "Events",
          "isSearchable": true,
          "isApplicable": true
        }
      ]
    }
  ],
  "nextPageLink": "https://api.securevan.com:443/v4/codes?parentCodeId=20513&$expand=supportedEntities&$top=3&$skip=3",
  "count": 5
}

GET/codes/{codeId}

Retrieve a Code
Description

Use this endpoint to retrieve an existing Code and its supported Entities.

Request
Parameter Location Type Description
codeId route int Required; Unique identifier of an existing Code
GET /codes/20548
Response

Returns a standard Code object, if found.

If the specified Code does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

POST/codes

Creates a new Code
Description

Use this endpoint to create a new Code in the current context.

Request

Accepts a standard Code object with no read-only values specified.

In this example, we’re creating a Code called AFL-CIO which is a child of parentCodeId 20515 and applicable to Events and Locations.

POST /codes
{
  "parentCodeId": 20515,
  "name": "AFL-CIO",
  "supportedEntities": [
    {
      "name": "Events",
      "isSearchable": true,
      "isApplicable": true
    },
    {
      "name": "Locations",
      "isSearchable": true,
      "isApplicable": true
    }
  ]
}
Response

If successful, the endpoint responds with HTTP Status Code 201 Created and the integer ID of the created Code in the response body. It also sets the Location header to the location of the newly created Code.

Responses to invalid requests follow the standard for input validation responses.

PUT/codes/{codeId}

Update an existing Code
Description

Use this endpoint to update the editable properties of an existing Code. For example, you could use this to change the name of a Code, to change a Code’s parent, or to add or remove the Entities this Code supports.

When constructing your request, note that all properties must be specified otherwise it is assumed they should be removed or set to null. In other words, if the supportedEntities property is set to null or [] (an empty array) in the request, all supported Entities are removed from the Code.

Request

Accepts a standard Code object with no read-only values specified except codeId.

Parameter Location Type Description
codeId route int Required; Unique identifier for an editable Code

The following example modifies the Code created in the POST /codes example by:

  • Changing the name
  • Adding searchable-only Entity support for Organizations
PUT /codes/20547
{
  "codeId": 20547,
  "parentCodeId": 20515,
  "name": "AFL and CIO",
  "supportedEntities": [
    {
      "name": "Events",
      "isSearchable": true,
      "isApplicable": true
    },
    {
      "name": "Locations",
      "isSearchable": true,
      "isApplicable": true
    },
    {
      "name": "Organizations",
      "isSearchable": true,
      "isApplicable": false
    }
  ]
}
Response

If the specified Code does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

Responses to invalid requests follow the standard for input validation responses.

DELETE/codes/{codeId}

Deletes an existing Code
Description

Use this endpoint to delete an existing Code. Use with caution as this this action is irreversible.

Codes can only be deleted if they are not applied to any Entity in any context in which the Code exists. NB: you may not have access to every context in which the Code exists.

Request
Parameter Location Type Description
codeId route int Required; Unique identifier for an editable Code
DELETE /codes/20547
Response

If the specified Code does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If the specified Code does exist but is not deletable, this endpoint will return an error with HTTP Status Code 403 Forbidden.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

Events

Overview

VAN’s Event Calendar system is used to track the participation of your volunteers, members, and activists at calendar events. Organizers use this system to track events like House Parties, Campaign Rallies, Phone Banks, and more. The Event system is designed to allow some campaigns and organizations a high degree of complexity, but is easily scalable down to the local level where such sophistication may be less desired. This varying degree of sophistication is facilitated by Event Types which allow users to set defaults for which Roles are available for volunteers, how many Locations the event has, whether volunteers may sign up for multiple Shifts, and more. Use this endpoint to create, update, and delete specific Events, and to find existing Events.

See Event Types for additional information about Event configuration rules.

Use the Signups endpoint to record a person’s participation at Events.

A Note About Dates and Times:

Dates and Times in Event-related endpoints are ISO 8601 formatted and respect UTC timezone offsets (which are similar to time zones). If no UTC offset is specified, the target context’s default timezone offset is used. In cases where an endpoint expects a time property, the input should still be in the form of a date and time. The system will simply ignore the date portion of the value.

Additionally, dates must always be in the 20th or 21st century (01 Jan 190001 Jan 2100).

A Note About Simple Objects:

Events are often related to other objects exposed by the API. Some of these objects are simply referenced by—but not modified by—the Events endpoint. References to these objects use a minimal, or Simple representation of the object; if a type is described as simple, the only requirement when sending a request is the unique identifier for that object (e.g., the simple Event Type object only has an eventTypeId property). Other properties, if specified, will be ignored.

In some cases, the Events endpoint will also return a simple object. In this case, it is typically just the unique identifier and the name for that object.

The Common Model section below indicates the full representation of the object as it would appear in a GET request. However, when POSTing or PUTting Events, the simple representation of the object is sufficient. For example, when creating an event with a single Location, it is sufficient to provide the locationId of the existing Location, rather than a full representation of that Location.

A Note About String Properties:

String properties of Events and related objects use standard input validation rules.

A Note About Recurring Events:

Recurring Events cannot be created via the API. However, Recurring Events created via the VAN UI can be retrieved and queried for. Additionally, you can update and delete individual instances of a Recurring Event.

Common Models

The following is an example of a Phone Bank Event called Neighbors Calling Neighbors on June 1, 2015 from 3PM to 8PM EDT. It has two locations, two codes, two notes, two roles, three shifts, and one linked voter registration batch.

{
  "eventId": 1370,
  "name": "Neighbors Calling Neighbors",
  "shortName": "NeighborCall",
  "description": "Come help get the word out about our great campaign.",
  "startDate": "2015-06-01T15:00:00-04:00",
  "endDate": "2015-06-01T20:00:00-04:00",
  "eventType": {
    "eventTypeId": 143856,
    "name": "Phone Bank"
  },
  "isOnlyEditableByCreatingUser": false,
  "isPubliclyViewable": null,
  "locations": [
    {
      "locationId": 272,
      "name": "Campaign HQ",
      "displayName": "Campaign HQ, 48 Grove St Somerville, MA 02144-2500 ",
      "address": {
        "addressId": null,
        "addressLine1": "48 Grove St",
        "addressLine2": null,
        "addressLine3": null,
        "city": "Somerville",
        "stateOrProvince": "MA",
        "zipOrPostalCode": "02144",
        "geoLocation": {
          "lon": -71.120121,
          "lat": 42.396363
        },
        "countryCode": "US",
        "preview": "48 Grove St \r\nSomerville, MA 02144-2500 ",
        "type": null,
        "isPreferred": null
      },
      "id": 272,
      "notes": null,
      "codes": null
    },
    {
      "locationId": 273,
      "name": "Northwest Regional Field Office",
      "displayName": "Northwest Regional Field Office, 800 Oak St Salem, MA 02111 ",
      "address": {
        "addressId": null,
        "addressLine1": "800 Oak St",
        "addressLine2": null,
        "addressLine3": null,
        "city": "Salem",
        "stateOrProvince": "MA",
        "zipOrPostalCode": "02111",
        "geoLocation": null,
        "countryCode": "US",
        "preview": "800 Oak St \r\nSalem, MA 02111 ",
        "type": null,
        "isPreferred": null
      },
      "id": 273,
      "notes": null,
      "codes": null
    }
  ],
  "codes": [
    {
      "codeId": 20516,
      "parentCodeId": 20513,
      "name": "Seniors",
      "codePath": "",
      "createdByName": "",
      "dateCreated": "2015-04-05T13:00:00Z",
      "supportedEntities": null
    },
    {
      "codeId": 20518,
      "parentCodeId": 20513,
      "name": "Youth",
      "codePath": "",
      "createdByName": "",
      "dateCreated": "2015-04-05T13:02:00Z",
      "supportedEntities": null
    }
  ],
  "notes": [
    {
      "noteId": 6,
      "text": "Sed ut perspiciatis unde omnis iste natus error sit ... qui dolorem eum fugiat quo voluptas nulla pariatur?",
      "isViewRestricted": true,
      "category": null,
      "createdDate": "2015-04-05T13:21:00Z"
    },
    {
      "noteId": 5,
      "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut ... deserunt mollit anim id est laborum.",
      "isViewRestricted": false,
      "category": null,
      "createdDate": "2015-04-05T13:20:00Z"
    }
  ],
  "shifts": [
    {
      "eventShiftId": 2162,
      "name": "Setup",
      "startTime": "2015-06-01T15:00:00-04:00",
      "endTime": "2015-06-01T16:00:00-04:00"
    },
    {
      "eventShiftId": 2163,
      "name": "Early Shift",
      "startTime": "2015-06-01T16:00:00-04:00",
      "endTime": "2015-06-01T18:00:00-04:00"
    },
    {
      "eventShiftId": 2164,
      "name": "Late Shift",
      "startTime": "2015-06-01T18:00:00-04:00",
      "endTime": "2015-06-01T20:00:00-04:00"
    }
  ],
  "roles": [
    {
      "roleId": 111687,
      "name": "Host",
      "isEventLead": true,
      "min": null,
      "max": null,
      "goal": null
    },
    {
      "roleId": 111689,
      "name": "Phone Banker",
      "isEventLead": false,
      "min": 5,
      "max": null,
      "goal": 20
    }
  ],
  "districtFieldValue": "003",
  "voterRegistrationBatches": [
    {
      "voterRegistrationBatchId": 123456
    }
  ],
  "createdDate": "2015-04-05T13:18:00Z"
}

The following is an overview of the Event object and its related objects. In some cases, the related object has a dedicated endpoint. In these cases, a link to those endpoints is provided.

Event
Property Type Description
eventId int Read-only; Unique identifier for an Event in this context
name string A name for this Event, no longer than 500 characters
shortName string A shorter name for this Event, no longer than 12 characters
description string An optional description for this Event, no longer than 500 characters
startDate datetime A start date and time for this Event
endDate datetime An end date and time for this Event that is after startDate
eventType object Required; read-only after Event creation; a simple Event Type for the current context
isOnlyEditableByCreatingUser bool Optional; If true, prevents modification of this Event by any users other than the user associated with the API context. Setting this to true effectively makes the Event read-only in the VAN interface. Defaults to false.
isPubliclyViewable bool Optional; Used by NGP VAN’s website platform to indicate whether this Event can be viewed publicly
locations array An array of zero or more simple Locations where the Event is to take place
codes array An array of zero or more simple Codes that are applied to this Event for organizational purposes
notes array An array of zero or more Notes that are applied to this Event
shifts array An array of one or more Shifts participants may sign up for at this Event
roles array An array of one or more Roles participants may have at this Event. The roles indicated must be a subset of the roles available for the event’s Event Type
districtFieldValue string If events are organized by a District Field in this context, this optional property should be a valid value for the District Field, and indicates, e.g. “this event is related to Congressional District 003.”
voterRegistrationBatches array An array of zero or more Voter Registration Batches that are linked to this Event
createdDate datetime Read-only; the date and time this Event was created
Note

Notes are user entered text associated with an Event.

Property Type Description
noteId int Read-only; Unique identifier for this Note
text string The text of a the note, no longer than 500 characters
category object Optional; A simple Note Category for this Note. Note Categories must be enabled in the target VAN context and the category must be applicable to Events.
isViewRestricted bool Optional; indicates whether the note is only visible to users with the ability to see restricted notes. Defaults to false.
createdDate datetime Read-only; the date and time this Note was created
Shift

Events can divided in to multiples Shifts, each with a custom time range and name (e.g., Setup, Morning, Afternoon, Evening, Clean Up, etc.). Even Events with an Event Type that prohibits Events from having multiple Shifts must have one element in the shifts array (even if the startTime and endTime are the same as the Event’s).

Property Type Description
eventShiftId int Read-only; Unique-identifier for this Shift
name string A name for this Shift, no longer than 15 characters and does not need to be unique
startTime datetime A start time for this Shift which is assumed to be on the same date as the event. If the shift’s start date differs from that of the event, VAN will use the event’s date and the shift’s start time.
endTime datetime An end time for this Shift that is after startTime but no more than 24 hours later.g
Role

A Role is flexible means of recording volunteer commitments, tasks, and assignments within an Event.

Property Type Description
roleId int Read-only; Unique identifier for a Role that is available to the Event’s Event Type
name string Read-only; the name of this Role, no longer than 50 characters
isEventLead int Indicates that participants with this Role are leaders of an Event (e.g., hosts). Defaults to false.
min int Optional; The minimum number of participants for this Role the Event should allow
max int Optional; The maximum number of participants, or capacity, for this Role the Event should allow (NB: this is a suggested maximum and is not enforced when creating a Signup)
goal int Optional; The target number of participants for this Role the Event should allow
Voter Registration Batch

If voters were registered at an event, the resulting Voter Registration Batches for those voters can be linked back to the corresponding event using this property. Multiple batches can be linked to a single event. This property should not be used when an event was not related to voter registration.

In order to successfully POST or PUT Voter Registration Batch data, the following validation checks must be satisfied:

  • Batch linking must be supported in the current context
  • The eventType of the passed event must support batch linking
  • The batch referenced in a passed voterRegistrationBatchId must already exist, must be available to the current user, and must not already be linked to another event
  • The final state of the event, with respect to linked batches, must not exceed certain limits: at most one Applicant batch, and at most one Pledge batch, may be linked to an event. (Although in some contexts, Applicant or Pledge batches may not be available at all.)
Property Type Description
voterRegistrationBatchId int Unique identifier for the Voter Registration Batch in question

GET/events

Find Events
Description

Use this endpoint to find Events available in the current context using a number of filter options.

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

By default, this endpoint returns 10 records per request. A maximum of 50 records per request is allowed via the $top parameter.

Valid expansion properties are: locations, codes, shifts, roles, notes, voterRegistrationBatches. Note that the number of $expand sections requested may impact the speed with which this endpoint will respond.

The endpoint takes the following optional filter parameters:

Parameter Location Type Description
codeIds query int Filters Events to those with the given Code(s) applied (multiple codeIds should be comma delimited)
eventTypeIds query int Filters Events to those of the given Event Type(s) (multiple eventTypeIds should be comma delimited)
inRepetitionWithEventId query int Filters to Recurring Events that are recurrences of the given Event ID
startingAfter query date Filters Events to those starting after (and not including) a given date (in the format yyyy-MM-dd)
startingBefore query date Filters Events to those starting before (and not including) a given date (in the format yyyy-MM-dd)
districtFieldValue query string Filters Events to those which are associated with the specified District Field Value
GET /events?startingAfter=2015-05-31&$expand=shifts&$top=2&districtFieldValue=003
Response

This endpoint responds with a standard paged response of Events.

{
  "items": [
    {
      "eventId": 1370,
      "name": "Neighbors Calling Neighbors",
      "shortName": "NeighborCall",
      "description": "Come help get the word out about our great campaign.",
      "startDate": "2015-06-01T15:00:00-04:00",
      "endDate": "2015-06-01T20:00:00-04:00",
      "eventType": {
        "eventTypeId": 143856,
        "name": "Phone Bank"
      },
      "isOnlyEditableByCreatingUser": false,
      "isPubliclyViewable": null,
      "locations": null,
      "codes": null,
      "notes": null,
      "shifts": [
        {
          "eventShiftId": 2162,
          "name": "Setup",
          "startTime": "2015-06-01T15:00:00-04:00",
          "endTime": "2015-06-01T16:00:00-04:00"
        },
        {
          "eventShiftId": 2163,
          "name": "Early Shift",
          "startTime": "2015-06-01T16:00:00-04:00",
          "endTime": "2015-06-01T18:00:00-04:00"
        },
        {
          "eventShiftId": 2164,
          "name": "Late Shift",
          "startTime": "2015-06-01T18:00:00-04:00",
          "endTime": "2015-06-01T20:00:00-04:00"
        }
      ],
      "roles": null,
      "districtFieldValue": "003",
      "voterRegistrationBatches": null,
      "createdDate": "2015-04-05T13:18:00Z"
    },
    {
      "eventId": 1371,
      "name": "Neighbors Calling Neighbors",
      "shortName": "NeighborCall",
      "description": "Come help get the word out about our great campaign.",
      "startDate": "2015-06-02T15:00:00-04:00",
      "endDate": "2015-06-02T20:00:00-04:00",
      "eventType": {
        "eventTypeId": 143856,
        "name": "Phone Bank"
      },
      "isOnlyEditableByCreatingUser": false,
      "isPubliclyViewable": null,
      "locations": null,
      "codes": null,
      "notes": null,
      "shifts": [
        {
          "eventShiftId": 2165,
          "name": "Setup",
          "startTime": "2015-06-01T15:00:00-04:00",
          "endTime": "2015-06-01T16:00:00-04:00"
        },
        {
          "eventShiftId": 2166,
          "name": "Early Shift",
          "startTime": "2015-06-01T16:00:00-04:00",
          "endTime": "2015-06-01T18:00:00-04:00"
        },
        {
          "eventShiftId": 2167,
          "name": "Late Shift",
          "startTime": "2015-06-01T18:00:00-04:00",
          "endTime": "2015-06-01T20:00:00-04:00"
        }
      ],
      "roles": null,
      "districtFieldValue": null,
      "voterRegistrationBatches": null,
      "createdDate": "2015-04-05T13:45:00Z"
    }
  ],
  "nextPageLink": "https://api.securevan.com:443/v4/events?startingAfter=2015-05-31&$expand=shifts&$top=2&$skip=2",
  "count": 5
}

GET/events/{eventId}

Retrieve a specific Event
Description

Use this endpoint to retrieve the details of a specific Event.

Use the Signups endpoint to retrieve a list of the Event’s participants.

Request
Parameter Location Type Description
eventId route int Required; Unique identifier of an Event to be retrieved
$expand query string Optional; comma delimited list of expansion properties: locations, codes, shifts, roles, notes, voterRegistrationBatches
GET /events/546454?$expand=locations,codes
Response

Returns a standard Event object, if found.

If the specified Event does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

POST/events

Create a new Event
Description

Use this endpoint to create a new Event.

Request

Accepts a standard Event object with simple types and no read-only values specified.

POST /events
{
  "name": "Neighbors Calling Neighbors",
  "shortName": "NeighborCall",
  "description": "Come help get the word out about our great campaign.",
  "startDate": "2015-06-02T15:00:00-04:00",
  "endDate": "2015-06-02T20:00:00-04:00",
  "eventType": {
    "eventTypeId": 143856
  },
  "isOnlyEditableByCreatingUser": false,
  "locations": [
    {
      "locationId": 273
    }
  ],
  "codes": [
    {
      "codeId": 20516
    },
    {
      "codeId": 20518
    }
  ],
  "notes": [
    {
      "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit...",
      "isViewRestricted": true
    }
  ],
  "shifts": [
    {
      "name": "Setup",
      "startTime": "2015-06-01T15:00:00-04:00",
      "endTime": "2015-06-01T16:00:00-04:00"
    },
    {
      "name": "Early Shift",
      "startTime": "2015-06-01T16:00:00-04:00",
      "endTime": "2015-06-01T18:00:00-04:00"
    },
    {
      "name": "Late Shift",
      "startTime": "2015-06-01T18:00:00-04:00",
      "endTime": "2015-06-01T20:00:00-04:00"
    }
  ],
  "roles": [
    {
      "roleId": 111687,
      "name": "Host",
      "isEventLead": true
    },
    {
      "roleId": 111689,
      "name": "Phone Banker",
      "isEventLead": false,
      "min": 5,
      "goal": 20
    }
  ],
  "voterRegistrationBatches": [
    {
      "voterRegistrationBatchId": 999
    },
    {
      "voterRegistrationBatchId": 1000
    }
  ],
  "districtFieldValue": "003"
}
Response

If successful, the endpoint responds with HTTP Status Code 201 Created and the integer ID of the created Event in the response body. It also sets the Location header to the location of the newly created Event.

Responses to invalid requests follow the standard for input validation responses.

POST/events/{eventId}/shifts

Create Shifts on existing Events
Description

Use this endpoint to add new Shifts to an existing Event. The advantages of this endpoint over the Update endpoint are that you needn’t know the other properties of an event and it will return the unique identifier of the new Shift.

Request
Parameter Location Type Description
eventId route int Required; Unique identifier for an editable Event

The body of this request is a standard Event Shift.

POST /events/234234/shifts
{
  "name": "Late Shift",
  "startTime": "2015-11-13T20:00:00-05:00",
  "endTime": "2015-11-13T22:00:00-05:00"
}
Response

If the specified Event does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If the specified Event does exist but is not editable, this endpoint will return an error with HTTP Status Code 403 Forbidden.

If successful, the endpoint responds with HTTP Status Code 201 Created and the integer ID of the created Shift in the response body.

Responses to invalid requests follow the standard for input validation responses.

PUT/events/{eventId}

Update an existing Event
Description

Use this endpoint to update the editable properties of an existing Event. When constructing your request, note that all properties must be specified otherwise it is assumed they should be removed or set to null. In other words, if the locations property is set to null or [] (an empty array) in the request, all Locations are removed from the Event. If removing all Locations violates the rules of the Event’s Event Type, a validation error will be returned.

Similarly, when constructing your request, collection properties should include all of the existing elements you wish to retain. For example, if you intend to add an additional Role to an event, you’ll need to pass the existing roles and the new Role. If you don’t, the new Role will be added and the existing Roles will be removed.

If you only intend to add Shifts to an existing Event, consider using the Shift creation endpoint.

Request
Parameter Location Type Description
eventId route int Required; Unique identifier for an editable Event

The validation rules for updating an Event are the same as the rules for creating an Event except that the read-only unique identifier properties such as eventId must also be sent.

Note that while it is possible to modify the startTime and endTime of an existing Shift, modification will not change the startTime or endTime of previously scheduled Signups to the Event.

The following example modifies the Event created in the POST /events example by:

  • Changing the name and shortName
  • Changing the locations (removing locationId 273 and adding locationId 272)
  • Removing all codes
  • Removing the Setup shift and extending the hours of the Early Shift
  • Changing the voterRegistrationBatches (removing the link to 999 and adding a link to 1001)
PUT /events/1374
{
  "eventId": 1374,
  "name": "Friends Calling Friends",
  "shortName": "FriendCall",
  "description": "Come help get the word out about our great campaign.",
  "startDate": "2015-06-02T15:00:00-04:00",
  "endDate": "2015-06-02T20:00:00-04:00",
  "eventType": {
    "eventTypeId": 143856
  },
  "isOnlyEditableByCreatingUser": false,
  "locations": [
    {
      "locationId": 272
    }
  ],
  "codes": [],
  "notes": [
    {
      "noteId": 10,
      "text": "Sed ut perspiciatis unde omnis iste natus...",
      "isViewRestricted": true
    },
    {
      "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit..."
    }
  ],
  "shifts": [
    {
      "eventShiftId": 2175,
      "name": "Early Shift",
      "startTime": "2015-06-01T15:00:00-04:00",
      "endTime": "2015-06-01T18:00:00-04:00"
    },
    {
      "eventShiftId": 2176,
      "name": "Late Shift",
      "startTime": "2015-06-01T18:00:00-04:00",
      "endTime": "2015-06-01T20:00:00-04:00"
    }
  ],
  "roles": [
    {
      "roleId": 111687,
      "name": "Host",
      "isEventLead": true,
      "min": null,
      "max": null,
      "goal": null
    },
    {
      "roleId": 111689,
      "name": "Phone Banker",
      "isEventLead": false,
      "min": 5,
      "max": null,
      "goal": 20
    }
  ],
  "voterRegistrationBatches": [
    {
      "voterRegistrationBatchId": 1000
    },
    {
      "voterRegistrationBatchId": 1001
    }
  ],
  "districtFieldValue": "004"
}
Response

If the specified Event does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If the specified Event does exist but is not editable, this endpoint will return an error with HTTP Status Code 403 Forbidden.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

Responses to invalid requests follow the standard for input validation responses.

DELETE/events/{eventId}

Deletes the specified existing event and all related signups
Description

Use this endpoint to delete an existing Event and its related Signups. Use with caution as this this action is irreversible. If the Event is part of a recurring series of Events, the other Events in the series will remain untouched.

If the Event is linked to any Voter Registration Batches, the links will be removed.

Request
Parameter Location Type Description
eventId route int Required; Unique identifier for an editable Event
DELETE /events/234234
Response

If the specified Event does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If the specified Event does exist but is not editable, this endpoint will return an error with HTTP Status Code 403 Forbidden.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

Event Types

Overview

VAN’s Events system can be used to track all kinds of events: House Parties, Campaign Rallies, Phone Banks, and any other type of event your organization hosts. While each of these types share common traits, they can also have requirements that significantly change how an event is represented. For example, a Campaign Rally is likely to occur on a specific day at a specific location, while a Phone Bank may occur every night until Election Day at many of your organization’s offices. Similarly, an organization may ask supporters to host House Parties on a specific date across the state. These “rules” are, in effect, “templates” for events, or Event Types. Use this endpoint to retrieve information about all available Event Types. These Event Types will serve as the basis for validation rules when creating or updating Events.

Event Types can only be created or edited using the VAN UI.

Common Models

The following is an example of a Phone Bank Event Type. Events of this type have the following rules:

  • Events can have more than one Shift
  • A Location isn’t required, but an Event can have more than one Location
  • Can have the Host and/or Phone Banker Roles
  • Each Role can have fulfillment Goals and minimum requirements but cannot have maximum capacity requirements
  • Signups to Events of this type can only have one of the following Statuses: Invited, Scheduled, Declined, Confirmed, Completed, or Walk In
  • Events are displayed in purple (#C6AFDA) in the VAN UI
  • When creating Events in the VAN UI, Campaign HQ is offered as the default Location
  • When creating Events in the VAN UI, users can create Repeatable Events
{
  "eventTypeId": 143856,
  "name": "Phone Bank",
  "canHaveMultipleShifts": true,
  "canHaveMultipleLocations": true,
  "canHaveGoals": true,
  "canHaveRoleMaximums": false,
  "canHaveRoleMinimums": true,
  "canBeRepeatable": true,
  "roles": [
    {
      "roleId": 111687,
      "name": "Host",
      "isEventLead": true
    },
    {
      "roleId": 111689,
      "name": "Phone Banker",
      "isEventLead": false
    }
  ],
  "statuses": [
    {
      "statusId": 4,
      "name": "Invited"
    },
    {
      "statusId": 1,
      "name": "Scheduled"
    },
    {
      "statusId": 3,
      "name": "Declined"
    },
    {
      "statusId": 11,
      "name": "Confirmed"
    },
    {
      "statusId": 2,
      "name": "Completed"
    },
    {
      "statusId": 15,
      "name": "Walk In"
    }
  ],
  "color": "#C6AFDA",
  "isAtLeastOneLocationRequired": false,
  "defaultLocation": {
    "locationId": 272,
    "name": "Campaign HQ",
    "displayName": "Campaign HQ, 48 Grove St Somerville, MA 02144-2500 ",
    "address": {
      "addressId": null,
      "addressLine1": "48 Grove St",
      "addressLine2": null,
      "addressLine3": null,
      "city": "Somerville",
      "stateOrProvince": "MA",
      "zipOrPostalCode": "02144",
      "geoLocation": {
        "lon": -71.120121,
        "lat": 42.396363
      },
      "countryCode": "US",
      "preview": "48 Grove St \r\nSomerville, MA 02144-2500 ",
      "type": null,
      "isPreferred": null
    },
    "id": 272,
    "notes": null,
    "codes": null
  }
}

Each Event Type has the following properties:

Property Type Description
eventTypeId int Unique identifier for an Event Type in this context
name string A name for the Event Type, no longer than 20 characters
canHaveMultipleShifts bool Indicates that Events of this Event Type may have multiple Shifts
canHaveMultipleLocations bool Indicates that Events of this Event Type may have multiple Locations
canHaveGoals bool Indicates that Events of this Event Type may have goals for Roles (e.g., how many people would you like to recruit for a role?)
canHaveRoleMaximums bool Indicates that Roles of Events of this Event Type may have a maximum number of attendees (NB: this is a suggested maximum and is not enforced when creating a Signup)
canHaveRoleMinimums bool Indicates that Roles of Events of this Event Type may have a minimum number of attendees
canBeRepeatable bool Indicates that Events of this Event Type may repeat over multiple days when created in the VAN UI
roles array An array of one or more Role objects; these are the set of possible roles for Events of this Event Type
statuses array An array of one or more Status objects; these are the set of possible Event Statuses for Events of this Event Type
color string Optional; an HTML hexadecimal color code used to distinguish Events of this Event Type in the VAN UI
isAtLeastOneLocationRequired bool Indicates that Events of this Event Type must have at least one Location
defaultLocation object Optional; if specified, the default Location for Events of this Event Type when created in the VAN UI

GET/events/types

Retrieve available Event Types
Description

Use this endpoint to retrieve all Event Types that are available in the current context.

Request

This endpoint takes no parameters.

GET /events/types
Response

This endpoint responds with an array of standard Event Type objects.

GET/events/types/{eventTypeId}

Retrieve a specific Event Type
Description

Use this endpoint to retrieve information about a specific Event Type available in the current context.

Request
Parameter Location Type Description
eventTypeId route int Unique identifier for a specific Event Type
GET /events/eventTypes/234956
Response

A standard Event Type object, if found.

If the specified Event Type does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

Signups

Overview

An Event Signup (Signup for short) is a record of a person’s participation at an Event. A Signup corresponds to a unique combination of:

  • Person (person)
  • Event (event)
  • Shift (shift)
  • Role (role)

Additionally, a Signup has a Status (status) that indicates the person’s current participation disposition. Examples include Invited, Declined, or Scheduled. In the case of a multi-location Event, a Signup may also have a Location (location).

A person’s participation status may change. For example, a Signup may be created with a Status of Invited. If the person responds to the invitation, the status may change to Scheduled or Declined. Just before the event, an event organizer may call the person to confirm whether the person still plans to attend the event changing the status to Confirmed. After the event, an organizer may review the event’s sign-in sheet. Using that information, a person’s status may be updated to Completed or No Show. Use the Signup modification endpoint to change a Signup’s status.

Quite often, the purpose of an event is to organize volunteers for canvassing activities. In these cases, volunteers are usually assigned lists of people to canvass during the course of the event. It is possible to indicate which list(s) a volunteer canvassed by populating the printedLists or minivanExports properties of a signup.

Common Models

The following is an example of a Person’s (James W. Gordon) Signup for the Neighbors Calling Neighbors Event. James has been Invited to be the Host during Shift 2452 (specifically from 3PM to 4PM) at Campaign HQ. During this event, James will be responsible for contacting the people on printed list 15981815-49117 and 15982500-51399, as well as MiniVAN exports 2186 and 2187.

{
  "eventSignupId": 2452,
  "person": {
    "vanId": 100476252,
    "firstName": "James",
    "middleName": "Worthington",
    "lastName": "Gordon"
  },
  "event": {
    "eventId": 1370,
    "name": "Neighbors Calling Neighbors",
    "shortName": "NeighborCall"
  },
  "shift": {
    "eventShiftId": 2162,
    "name": null
  },
  "role": {
    "roleId": 111687,
    "name": "Host"
  },
  "status": {
    "statusId": 4,
    "name": "Invited"
  },
  "location": {
    "locationId": 272,
    "name": "Campaign HQ",
    "displayName": "Campaign HQ, 48 Grove St Somerville, MA 02144-2500"
  },
  "startTimeOverride": "2015-06-01T15:00:00-04:00",
  "endTimeOverride": "2015-06-01T16:00:00-04:00",
  "printedLists": [
    {
      "number": "15981815-49117",
      "name": "Test Turf 01",
    },
    {
      "number": "15982500-51399",
      "name": "Test Turf 02",
    }
  ],
  "minivanExports": [
    {
      "minivanExportId": 2186,
      "name": "My List 10/9/15 4:23 PM",
      "databaseMode": 0
    },
    {
      "minivanExportId": 2187,
      "name": "My List 10/9/15 4:34 PM",
      "databaseMode": 1
    }
  ]
}
Signup

The overall Signup object has a number of properties with simple object values. Only simple objects’ unique identifiers are required.

Property Type Description
eventSignupId int Read-only; Unique identifier for this Signup
person object Required; An accessible Person
event object Required; A simple Event to sign up for
shift object Required; A simple Shift of the Event
role object Required; A simple Role for this person to play
status object Required; A signup Status (e.g., “Invited”)
location object Required if event has Locations; If specified, a Location that is available to this Event
startTimeOverride datetime Optional; If specified, overrides the startTime of the associated shift and requires that endTimeOverride must also be set
endTimeOverride datetime Optional; If specified, overrides the endTime of the associated shift and requires that startTimeOverride must be set to an earlier time
printedLists array A list of Printed Lists indicating people who will be contacted by this Person during the event.
minivanExports array A list of MiniVAN Exports indicating people who will be contacted by this Person during the event.
Person
Property Type Description
vanId int Required; Unique identifier for an accessible person
firstName string Read-only; A person’s first name, no longer than 20 characters
middleName string Read-only; A person’s middle name, no longer than 20 characters
lastName string Read-only; A person’s last name, no longer than 25 characters
Event
Property Type Description
eventId int Required; Unique identifier for an accessible Event
name string Read-only; A name for this Event, no longer than 500 characters
shortName string Read-only; A shorter name for this Event, no longer than 12 characters
Shift
Property Type Description
eventShiftId int Required; Unique identifier for a Shift of this Event
name string Read-only; A name for this Shift, no longer than 15 characters
Role
Property Type Description
roleId int Required; Unique identifier for a Role available to this Event
name string Read-only; The name of this Role, no longer than 50 characters
Status
Property Type Description
statusId int Required; Unique identifier for a Status available to this Event (as specified by the Event Type)
name string Read-only; The name of this Status, no longer than 10 characters
Location
Property Type Description
locationId int Required; Unique identifier for an existing Location
name string Read-only; The name of this Location, no longer than 50 characters
displayName string Read-only; The name and address of this Location, no longer than 200 characters

GET/signups/statuses

Retrieve Signup Statuses
Description

Use this endpoint to retrieve all valid Signup Statuses for a given Event or for any Event of a given Event Type.

The information returned by this endpoint changes only as frequently as an Event Type changes (which is typically not very often in production). Consider caching the results of this endpoint.

Request

This endpoint requires one of the following two parameters:

Parameter Location Type Description
eventId query int Filters Statuses to just those available to this Event (based on its Event Type). Required if eventTypeId is not specified.
eventTypeId query int Optional; Filters Statuses to just those available to this Event Type. Required if eventId is not specified.
GET /signups/statuses?eventTypeId=143856
Response

This endpoint responds with an array of Status objects.

[
  {
    "statusId": 2,
    "name": "Completed"
  },
  {
    "statusId": 11,
    "name": "Confirmed"
  },
  {
    "statusId": 3,
    "name": "Declined"
  },
  {
    "statusId": 4,
    "name": "Invited"
  },
  {
    "statusId": 1,
    "name": "Scheduled"
  },
  {
    "statusId": 15,
    "name": "Walk In"
  }
]

GET/signups/{eventSignupId}

Retrieve a specific Signup
Description

Use this endpoint to retrieve a specific Event Signup.

Request
Parameter Location Type Description
eventSignupId route int Required; Unique identifier of an existing event shift
GET /signups/2452
Response

This endpoint returns a standard Signup object, if found.

If the specified Signup does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

GET/signups

Retrieve Signups for an Event or Person
Description

Use this endpoint to find all of a Person’s Signups (across all Events) or to find all of the Signups for a specific Event.

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

Additional parameters include:

Parameter Location Type Description
eventId query int Unique identifier for an Event. Required if vanId is not specified.
vanId query int Unique identifier for a Person. Required if eventId is not specified.
hasPrintedList query bool Optional; if true, shows only signups with printed lists attached; if false, shows only signups without printed lists attached. If omitted, does not filter by printed list attachment at all.
hasMinivanExport query bool Optional; if true, shows only signups with MiniVAN exports attached; if false, shows only signups without MiniVAN exports attached. If omitted, does not filter by MiniVAN exports attachment at all.
$expand query string Optional; comma delimited list of expansion properties: printedLists, minivanExports

Either the eventId parameter, or the vanId parameter, must be specified.

GET /signups?vanId=100476252&$expand=printedLists,minivanExports&hasPrintedList=true&hasMinivanExport=true
Response

This endpoint responds with a standard paged response of Signups.

If vanId is specified but the Person is not accessible, this endpoint will return an error with HTTP Status Code 403 Forbidden.

If vanId is specified but the Person does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If eventId is specified but the Event does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

{
  "items": [
    {
      "eventSignupId": 2452,
      "person": {
        "vanId": 100476252,
        "firstName": "James",
        "middleName": "Worthington",
        "lastName": "Gordon"
      },
      "event": {
        "eventId": 1370,
        "name": "Neighbors Calling Neighbors",
        "shortName": "NeighborCall"
      },
      "shift": {
        "eventShiftId": 2162,
        "name": null
      },
      "role": {
        "roleId": 111687,
        "name": "Host"
      },
      "status": {
        "statusId": 4,
        "name": "Invited"
      },
      "location": {
        "locationId": 272,
        "name": "Campaign HQ",
        "displayName": "Campaign HQ, 48 Grove St Somerville, MA 02144-2500 "
      },
      "startTimeOverride": "2015-06-01T15:00:00-04:00",
      "endTimeOverride": "2015-06-01T16:00:00-04:00",
      "printedLists": [
        {
          "number": "15981815-49117",
          "name": "Test Turf 01",
        },
        {
          "number": "15982500-51399",
          "name": "Test Turf 02",
        }
      ],
      "minivanExports": [
        {
          "minivanExportId": 2186,
          "name": "My List 10/9/15 4:23 PM",
          "databaseMode": 0
        },
        {
          "minivanExportId": 2187,
          "name": "My List 10/9/15 4:34 PM",
          "databaseMode": 1
        }
      ]
    },
    {
      "eventSignupId": 2453,
      "person": {
        "vanId": 100476252,
        "firstName": "James",
        "middleName": "Worthington",
        "lastName": "Gordon"
      },
      "event": {
        "eventId": 1373,
        "name": "Neighbors Calling Neighbors",
        "shortName": "NeighborCall"
      },
      "shift": {
        "eventShiftId": 2172,
        "name": null
      },
      "role": {
        "roleId": 111689,
        "name": "Phone Banker"
      },
      "status": {
        "statusId": 1,
        "name": "Scheduled"
      },
      "location": null,
      "startTimeOverride": "2015-06-01T16:00:00-04:00",
      "endTimeOverride": "2015-06-01T18:00:00-04:00",
      "printedLists": [
        {
          "number": "15981815-59117",
          "name": "Test Turf 03",
        },
        {
          "number": "15982500-61399",
          "name": "Test Turf 04",
        }
      ],
      "minivanExports": [
        {
          "minivanExportId": 3186,
          "name": "My List 10/9/15 6:23 PM",
          "databaseMode": 0
        },
        {
          "minivanExportId": 3187,
          "name": "My List 10/9/15 6:34 PM",
          "databaseMode": 1
        }
      ]
    }
  ],
  "nextPageLink": null,
  "count": 2
}

POST/signups

Create or modify Signup records
Description

Use this endpoint to record a Person’s participation at an Event. Because it’s not easy to know whether a Person is already signed up for an Event, this endpoint will create a new Signup only if a Signup with the same Person, Event, Role, and Shift does not already exist. If a Signup does exist, it will override the existing Signup’s Status, Start Time, End Time, and (if specified) Location. A record of this change is displayed in the VAN UI.

When a Signup is created or updated, a canvass response is generated to represent the signup interaction. The Input Type is API, the Date Canvassed is the current date, the Canvasser is the API user associated with the current context, and the Result Code corresponds to a result most appropriate for the given Status (e.g., ScheduledCanvassed ). Consult the VAN UI for a detailed mapping.

If appropriate, one or more Printed Lists may be specified, to indicate that the Person specified in this request will be assigned to canvass the indicated lists. Similarly, one or more MiniVAN Exports may be specified to indicate that the Person specified in this request will be assigned to canvass the indicated exports.

Request

This endpoint accepts a standard Signup object with simple types and no read-only values specified.

POST /signups
{
  "person": {
    "vanId": 100476252
  },
  "event": {
    "eventId": 1370
  },
  "shift": {
    "eventShiftId": 2162
  },
  "role": {
    "roleId": 111687
  },
  "status": {
    "statusId": 4
  },
  "location": {
    "locationId": 272
  },
  "printedLists": [
    {
      "number": "16531169-91998"
    },
    {
      "number": "16531169-91999"
    }
  ],
  "minivanExports": [
      {
        "minivanExportId": 2186,
        "databaseMode": 0
      },
      {
        "minivanExportId": 2187,
        "databaseMode": 1
      }
  ]
}
Response

If successful, the endpoint responds with HTTP Status Code 201 Created (even if it matched and updated an existing Signup) and the integer ID of the created Signup in the response body. It also sets the Location header to the location of the newly created Signup.

Responses to invalid requests follow the standard for input validation responses.

PUT/signups/{eventSignupId}

Update an existing Signup
Description

Use this endpoint to update a specific existing Signup. A record of this change is displayed in the VAN UI.

A Signup’s Event and Person properties are immutable after creation. If you want to sign up a Person for a different Event, first delete the existing Signup and create a new one.

If you do not know the eventSignupId, consider using the create or modify endpoint.

When a Signup is updated, a canvass response is generated to represent the signup interaction. The Input Type is API, the Date Canvassed is the current date, the Canvasser is the API user associated with the current context, and the Result Code corresponds to a result most appropriate for the given Status (e.g., ScheduledCanvassed ). Consult the VAN UI for a detailed mapping.

If appropriate, one or more printed lists may be specified, to indicate that the Person specified in this request will be assigned to canvass the indicated printed lists. Similarly, one or more MiniVAN Exports may be specified to indicate that the Person specified in this request will be assigned to canvass the indicated exports. All previous Printed List and MiniVAN Export assignments for this signup will be destructively overwritten by the new set of assignments.

Request

This endpoint accepts a standard Signup object with simple types and no read-only values specified except eventSignupId.

Parameter Location Type Description
eventSignupId route int Required; Unique identifier of an existing Signup

The following example changes the Location of the Signup created in the create example:

PUT /signups/2452
{
  "eventSignupId": 2452,
  "person": {
    "vanId": 100476252
  },
  "event": {
    "eventId": 1370
  },
  "shift": {
    "eventShiftId": 2162
  },
  "role": {
    "roleId": 111687
  },
  "status": {
    "statusId": 4
  },
  "location": {
    "locationId": 273
  },
  "printedLists": [
    {
      "number": "16531169-91998"
    },
    {
      "number": "16531169-81234"
    },
    {
      "number": "16531169-81235"
    }
  ],
  "minivanExports": [
    {
      "minivanExportId": 2186,
      "databaseMode": 0
    },
    {
      "minivanExportId": 2187,
      "databaseMode": 1
    }
  ]
}
Response

If the specified Signup does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

Responses to invalid requests follow the standard for input validation responses.

DELETE/signups/{eventSignupId}

Delete an existing Signup
Description

This endpoint deletes an existing Signup. Use with caution as this this action is irreversible and a record of this change is not display in the VAN UI.

Typically it’s more appropriate to update an existing Signup with a Status of Declined or No Show rather than to delete the record entirely.

Deleting a Signup does not delete any canvass responses associated with actions taken on the Signup.

Request
Parameter Location Type Description
eventSignupId route int Required; Unique identifier of an existing Signup
DELETE /signups/2423
Response

If the specified Signup does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

Locations

Overview

VAN Locations are first class objects that support other entities such as Events and Organizations. The idea behind Locations is that these entities can have common locations (e.g., a union hall is both the site of a Labor Union Local (Organization), and is the site that Local hosts a phone bank Event), and that these kinds of Locations have traits beyond just a name and address. These traits, some only accessible via the VAN UI, include Notes, Codes, and availability (i.e., what days of the week a Location is available).

Use this endpoint to create and delete specific Locations, and to find existing Locations. Locations can be associated with other entities using each supported entity’s endpoint.

Common Models

The following is an example of a Location called Campaign HQ.

{
  "locationId": 272,
  "name": "Campaign HQ",
  "displayName": "Campaign HQ, 48 Grove St Somerville, MA 02144-2500",
  "address": {
    "addressLine1": "48 Grove St",
    "addressLine2": null,
    "addressLine3": null,
    "city": "Somerville",
    "stateOrProvince": "MA",
    "zipOrPostalCode": "02144",
    "geoLocation": {
      "lon": -71.120121,
      "lat": 42.396363
    },
    "countryCode": "US",
    "preview": "48 Grove St \r\nSomerville, MA 02144-2500"
  }
}
Location
Property Type Description
locationId int Read-only; Unique identifier for a Location in this context
name string A name for this Location, no longer than 50 characters
displayName string Read-only; A display name for this Location that is the combination of the name and address.preview properties
address object Optional; an Address object for this Location
Address
Property Type Description
addressLine1 string Optional; First line of a Street Address
addressLine2 string Optional; Second line of a Street Address
addressLine3 string Optional; Third line of a Street Address
city string Optional; City or Town
stateOrProvince string Optional; Two or three character State or Province code (e.g., MN, ON, NSW, etc.)
zipOrPostalCode string Optional; ZIP, ZIP+4, Postal Code, Post code, etc.
geoLocation object Optional and Read-only; a Geographic Coordinate object for this Address (VAN will attempt to populate this for you)
countryCode string Optional; A two character ISO country code that is supported by your VAN context (e.g., US)
preview string Read-only; A multiple line preview of this Address which may contain Windows line breaks (\r\n)
Geographic Coordinate
Property Type Description
lon float Required; the longitude of this Coordinate that is between -180 and 180 (inclusive)
lat float Required; the latitude of this Coordinate that is between -90 and 90 (inclusive)

GET/locations

Find Locations
Description

Use this endpoint to find Locations available in the current context using a number of filter options.

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

By default, this endpoint returns 50 records per request. A maximum of 200 records per request is allowed via the $top parameter.

The endpoint takes the following optional filter parameters:

Parameter Location Type Description
name query string Filters to Locations with names that contain the given input
GET /locations?name=HQ
Response

This endpoint responds with a standard paged response of Locations.

{
  "items": [
    {
      "locationId": 272,
      "name": "Campaign HQ",
      "displayName": "Campaign HQ, 48 Grove St Somerville, MA 02144-2500",
      "address": {
        "addressLine1": "48 Grove St",
        "addressLine2": null,
        "addressLine3": null,
        "city": "Somerville",
        "stateOrProvince": "MA",
        "zipOrPostalCode": "02144",
        "geoLocation": {
          "lon": -71.120121,
          "lat": 42.396363
        },
        "countryCode": "US",
        "preview": "48 Grove St \r\nSomerville, MA 02144-2500"
      }
    }
  ],
  "nextPageLink": null,
  "count": 1
}

GET/locations/{locationId}

Retrieve a specific Location
Description

Use this endpoint to retrieve the details of a specific Location.

Request
Parameter Location Type Description
locationid route int Required; Unique identifier of a Location to be retrieved
GET /locations/272
Response

Returns a standard Location object, if found.

If the specified Location does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

POST/locations/findOrCreate

Looks for a matched Location, creates one if none exists
Description

Similar to the people/findOrCreate endpoint, this endpoint searches for the given Location. If a Location is found, the existing Location is returned. If a Location is not found, a new Location is created.

This endpoint is useful when synchronizing from a system that does not uniquely identify locations.

This endpoint parses the address provided, and uses the following criteria to find existing locations in US contexts:

  • If a name is provided and a ZIP5 can be determined (either provided or discovered based on city and stateOrProvince), and no Street Name can be parsed, a match will be attempted based on name and ZIP5
  • Then, if a name is provided and a ZIP5 cannot be determined and no Street Name can be parsed, a match will be attempted based on name, city, and stateOrProvince
  • Then, if a Street Name can be parsed and a ZIP5 can be determined (either provided or discovered based on city and stateOrProvince), a match will be attempted based on Street Number, Street Name, Apartment Number, and ZIP5

Non-US contexts match on exact name and parsed address.

Request

Accepts a standard Location object with no read-only values specified.

POST /locations/findOrCreate
{
 "name": "Campaign HQ",
 "address": {
   "addressLine1": "48 Grove St",
   "city": "Somerville",
   "stateOrProvince": "MA",
   "zipOrPostalCode": "02144"
 }
}
Response

If successful, the endpoint responds with HTTP Status Code 201 Created (even if it matched and updated an existing Location) and the integer ID of the created (or updated) Location in the response body. It also sets the Location header to the location of the Location.

Responses to invalid requests follow the standard for input validation responses.

POST/locations

Create a new Location
Description

Use this endpoint to create a new Location.

Typically it’s more appropriate to find or create a Location because you may not know whether a very similar Location already exists (e.g., was created in the VAN UI).

Request

Accepts a standard Location object with no read-only values specified.

POST /locations/findOrCreate
{
 "name": "Campaign HQ",
 "address": {
   "addressLine1": "48 Grove St",
   "city": "Somerville",
   "stateOrProvince": "MA",
   "zipOrPostalCode": "02144"
 }
}
Response

If successful, the endpoint responds with HTTP Status Code 201 Created and the integer ID of the created Location in the response body. It also sets the Location header to the location of the Location.

Responses to invalid requests follow the standard for input validation responses.

DELETE/locations/{locationId}

Deletes an existing Location
Description

Use this endpoint to delete an existing Location. Use with caution as this this action is irreversible. Events associated with the given Location will continue to function though the Signups associated with the now deleted Location will display “Invalid Location” in the VAN UI.

Request
Parameter Location Type Description
locationId route int Required; Unique identifier for an editable Location
DELETE /locations/272
Response

If the specified Location does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

If successful, the endpoint responds with HTTP Status Code 204 No Content and an empty response body.

Notes

Overview

Notes are incredibly useful for providing full text annotations to entities in VAN. Notes can be applied to People, Events, Locations, and Organizations. (NB: not all APIs have Note support yet).

Some VAN clients have an additional feature of Notes enabled called “Note Categories.” This feature allows users to categorize individual Notes. Further, each Note Category can be applicable to Notes of different entity types, or Note Category Types.

For example, you may have a Note Category called Venue Details. Notes in this Note Category may provide textual directions to a Location (e.g., “First house on the right”) or reminders for Event hosts (e.g., “Remember to turn off the lights”).

Which Note Category Types are available in your VAN context may vary. If you’d like the feature enabled, reach out to your VAN Administrator.

Use this endpoint to retrieve meta data about Note Categories and Note Category Types. Notes are applied using each supported entity’s endpoint. Use the VAN UI to create or edit Note Categories.

Common Models

The following is an example of a Note Category:

{
  "assignableTypes": [
    "Event",
    "Organization"
  ],
  "noteCategoryId": 23,
  "name": "Venue Directions"
}
Note Category

Each Note Category has the following properties:

Property Type Description
noteCategoryId int Read-only; Unique identifier for a Note Category in this context
name string A name for this Note Category
assignableTypes array Required; an array of zero or more strings representing the Type this Note Category can be applied to

GET/notes/categoryTypes

Retrieve available Note Category Types
Description

Use this endpoint to retrieve all available Note Category Types.

In almost all cases, the available types are:

  • Event
  • Location
  • Person
  • Organization
Request

This endpoint takes no parameters.

GET /notes/categoryTypes
Response

This endpoint returns an array of strings.

[
  "Person",
  "Organization",
  "Event",
  "Location"
]

GET/notes/categories

Retrieve available Note Categories
Description

Use this endpoint to retrieve all available Note Categories.

Note

Note Categories must be explicitly “opted in” to the current context’s Committee using the Committees picker on a categories detail page in the VAN UI. It is not enough for the Note Categories to be listed on the Note Categories List page.

Request

This endpoint takes no parameters.

GET /notes/noteCategories
Response

This endpoint returns an array of standard Note Category objects.

[
 {
   "assignableTypes": [
     "Event"
   ],
   "noteCategoryId": 24,
   "name": "Event Details"
 },
 {
   "assignableTypes": [
     "Event",
     "Organization"
   ],
   "noteCategoryId": 23,
   "name": "Venue Directions"
 }
]

GET/notes/categories/{noteCategoryId}

Retrieve a Note Category
Description

Use this endpoint to retrieve a specific Note Category.

Request
Parameter Location Type Description
noteCategoryId route int Required; Unique identifier of an existing Note Category
GET /notes/noteCategories/24
Response

Returns a standard Note Category object, if found.

If the specified Note Category does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.

Users

Overview

Users are people who can log in to the VAN. Some VAN clients may organize their users by district field values, as a way to indicate which user(s) have been assigned to which turf(s). A given user may be assigned multiple district field values, and a single district field value may be assigned to multiple users. Or a user may be assigned no district field values. The district field which is used to organize users is fixed, within each state, at the committee level.

For example, if the “Jane Casey for Senate” committee in Massachusetts is organized by Congressional District, it’s possible to organize users in that committee, as follows:

  • User 1234 is assigned to Congressional Districts “001” and “002”
  • User 1235 is assigned to Congressional Districts “002” and “003”
  • User 1236 has no Congressional District assignments

Common Models

The following is an example of a District Field Value assignment for a user:

{
    "districtFieldValues": [
      "W1P2",
      "W1P3",
      "W2P1"
    ]
}

In this case, the District Field which is used to organize users for the state and committee specified by the API key has district field values whose identifiers are “W1P2”, “W1P3”, and “W2P1”.

GET/users/{userId}/districtFieldValues

Gets district field values for a user
Description

Use this endpoint to retrieve all District Field Values assigned to a user

Request

This endpoint takes no parameters.

GET /users/1234/districtFieldValues
Response

This endpoint returns a standard User District Field Value Assignment.

{
    "districtFieldValues": [
      "W1P2",
      "W1P3",
      "W2P1"
    ]
}

POST/users/{userId}/districtFieldValues

Add new district field value assignments
Description

Use this endpoint to assign additional district field values to a user.

Request

The request is a standard User District Field Value Assignment.

POST /users/12345/districtFieldValues
{
    "districtFieldValues": [
      "W1P2",
      "W1P3",
      "W2P1"
    ]
}
Response

The response is the full set of district field value assignments for this user, and is thus an improper superset of the district field value assignments in the request.

{
    "districtFieldValues": [
      "W1P2",
      "W1P3",
      "W2P1",
      "W2P2",
      "W3P1"
    ]
}

PUT/users/{userId}/districtFieldValues

Add new district field value assignments
Description

Use this endpoint to completely overwrite the district field values assignments for a user.

Request

The request is a standard User District Field Value Assignment.

PUT /users/12345/districtFieldValues
{
    "districtFieldValues": [
      "W1P2",
      "W4P1"
    ]
}
Response

The response is the full set of district field value assignments for this user, and thus should be identical to the district field values in the request.

{
    "districtFieldValues": [
      "W1P2",
      "W4P1"
    ]
}

District Fields

Overview

A District Field is a geographic segmentation of a state into politically meaningful entities. Common district fields include “Congressional district”, “State senate district”, and “Precinct”. Each district field has multiple District Field Values, indicating the ways the state is segmented. For example, in Washington state, the Congressional district field may have District Field Values “01”, “02”, … “10”.

Some VAN clients have custom districts, which are used to segment a state according to divisions that are meaningful for that client. For example, a Minnesota custom district might have values like “Minneapolis/St. Paul”, “Rochester area”, etc.

Some districts are arranged into hierarchies; a single district in one field is composed of multiple districts from another field. In this case the first District Field is said to be the “parent” of the second District Field, and the values within the first District Field are said to be the “parents” of the values in the second District Field.

For example, in some states a State Senate district is composed of one or more State House districts: State Senate District “1234” is composed of State House Districts “10”, “11”, and “12”. In this case:

  • The “State Senate” District Field is said to be the parent of the “State House” District Field.
  • State Senate District Field Value “1234” is said to be the parent of State House District Field Values “10”, “11”, and “12”.

Common Models

The following is an example of a District Field:

{
    "districtFieldId": 999,
    "name": "State House",
    "parentFieldId": 888,
    "isCustomDistrict": false,
    "districtFieldValues": [
        {
            "id": "10",
            "name": "Jackson County District 10",
            "parentId": "1234"
        },
        {
            "id": "11",
            "name": "Jackson County District 11",
            "parentId": "1234"
        },
        {
            "id": "12",
            "name": "Jackson County District 12",
            "parentId": "1234"
        },
        {
            "id": "20",
            "name": "Jefferson County District 20",
            "parentId": "2345"
        }
    ]
}
District Field

Each District Field has the following properties:

Property Type Description
districtFieldId int Read-only; Unique identifier for a District Field
name string A name for this District Field
parentFieldId int Unique identifier for the District Field’s parent, or null if no such parent exists
isCustomDistrict bool Indicates whether the field is a custom district (true) or not (false)
districtFieldValues array List of valid District Field Values for this district
District Field Value

Each District Field Value has the following properties:

Property Type Description
id string Read-only; Unique identifier for the District Field Value
name string A name for this District Field Value
parentId string Unique identifier for the District Field Value’s parent, or null if no such parent exists (because the District Field Value lacks a parent)

GET/districtFields

Get all available district fields
Description

Use this endpoint to retrieve all District Fields

Request

This endpoint accepts the following parameters:

Parameter Location Type Description
custom query bool Whether to filter the list to only custom district fields (true), or not to filter the list (false). Default value is false.
organizeAt query bool Whether to filter the list to the district field used for organizing events and users (true), or not to filter the list (false). Default value is false.
GET /districtFieldValues?custom=false&organizeAt=false
Response

This endpoint returns an object whose districts property provides an array of District Field objects, without district field values.

{
  "districts": [
    {
        "districtFieldId": 888,
        "name": "State Senate",
        "parentFieldId": null,
        "isCustomDistrict": false,
    },
    {
        "districtFieldId": 889,
        "name": "State House",
        "parentFieldId": 888,
        "isCustomDistrict": false,
    },
    {
        "districtFieldId": 900,
        "name": "Minnesota Regions",
        "parentFieldId": null,
        "isCustomDistrict": true,
    }
  ]
}

GET/districtFields/{districtFieldId}

Get District Field
Description

Use this endpoint to get full details for a district field

Request

The request has no parameters

GET /districtFields/12345
Response

District Field.

Printed Lists

Overview

A Printed List contains a set of records from the VoterFile or MyCampaign which has been printed into a turf packet as part of a canvassing effort.

Note that Printed Lists expire over time. If a list has been associated with an event, then the association between the list and the event is persisted indefinitely; but the actual list is deleted after 90 days. If the list has not been associated with an event, then the list is deleted afer 30 days.

Common Models

The following is an example of a Printed List:

{
    "number": "15981815-49117",
    "name": "Test Turf 01",
    "eventSignups": [
        {
            "eventSignupId": 9333,
            "person": {
                "vanId": 100116333
            },
            "event": {
                "eventId": 70333
            },
            "shift": {
                "eventShiftId": 134333
            },
            "role": {
                "roleId": 333
            },
            "status": {
                "statusId": 4
            },
            "location": {
                "locationId": 5333
            },
            "startTimeOverride": "2015-09-08T14:00:00-04:00",
            "endTimeOverride": "2015-09-08T19:30:00-04:00",
        },
        {
            "eventSignupId": 9444,
            "person": {
                "vanId": 100116444
            },
            "event": {
                "eventId": 70444
            },
            "shift": {
                "eventShiftId": 134444
            },
            "role": {
                "roleId": 444
            },
            "status": {
                "statusId": 4
            },
            "location": {
                "locationId": 5444
            },
            "startTimeOverride": "2015-09-08T14:00:00-04:00",
            "endTimeOverride": "2015-09-08T19:30:00-04:00",
        }
    ]
}
Printed List

Each Printed List has the following properties:

Property Type Description
number string Read-only; Unique identifier for a Printed List
name string The name given to the list when it was printed on the front end
eventSignups array List of Event Signups to which this list has been assigned.

GET/printedLists

Get all available printed lists
Description

Use this endpoint to retrieve all available Printed Lists

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

By default, this endpoint returns 10 records per request. A maximum of 50 records per request is allowed via the $top parameter.

Valid expansion properties are: eventSignups. Note that the number of $expand sections requested may impact the speed with which this endpoint will respond.

The endpoint takes the following optional filter parameters:

Parameter Location Type Description
generatedAfter query date Filter result set by printed lists generated after the specified date.
generatedBefore query date Filter result set by printed lists generated before the specified date.
createdBy query int Filters result set ID of the VAN user who created the printed lists.
folderName query string Filters result set by lists in the specified folder name
turfName query string Filters result set by lists with the specified turf name
hasSignup query bool Optional; if true, shows only lists which are attached to event signups; if false, shows only lists which are not attached to event signups. If omitted, does not filter by signup attachment at all.
$expand query string Optional; comma delimited list of expansion properties: eventSignups
GET /printedLists?generatedAfter=2012-10-01&generatedBefore=2012-11-01&createdBy=123&folderName=GOTV&turfName=Precinct+1&hasSignup=true&$expand=eventSignups
Response

A paginated list of Printed List objects.

GET/printedLists/{printedListNumber}

Get Printed List
Description

Use this endpoint to get full details for a printed list

Request

The request has no parameters

GET /printedLists/16531169-91333
Response

Printed List.

MiniVAN Exports

Overview

A MiniVAN Export contains a set of records from the VoterFile or MyCampaign which has been exported to MiniVAN for use in canvassing efforts.

Common Models

The following is an example of a MiniVAN Export:

{
  "minivanExportId": 2133,
  "name": "My List 10/9/15 4:23 PM",
  "databaseMode": 0,
  "dateCreated": "2015-10-09T16:23:53.41Z",
  "createdBy": {
    "userId": 111222,
    "firstName": "Frances",
    "lastName": "Perkins"
  },
  "canvassers": [
    {
      "canvassserId": 111223,
      "firstName": "Eleanor",
      "lastName": "Roosevelt"
    }
  ],
  "eventSignups": [
    {
        "eventSignupId": 9333,
        "person": {
            "vanId": 100116333
        },
        "event": {
            "eventId": 70333
        },
        "shift": {
            "eventShiftId": 134333
        },
        "role": {
            "roleId": 333
        },
        "status": {
            "statusId": 4
        },
        "location": {
            "locationId": 5333
        },
        "startTimeOverride": "2015-09-08T14:00:00-04:00",
        "endTimeOverride": "2015-09-08T19:30:00-04:00",
    },
    {
        "eventSignupId": 9444,
        "person": {
            "vanId": 100116444
        },
        "event": {
            "eventId": 70444
        },
        "shift": {
            "eventShiftId": 134444
        },
        "role": {
            "roleId": 444
        },
        "status": {
            "statusId": 4
        },
        "location": {
            "locationId": 5444
        },
        "startTimeOverride": "2015-09-08T14:00:00-04:00",
        "endTimeOverride": "2015-09-08T19:30:00-04:00",
    }
  ]
}
MiniVAN Export

Each MiniVAN Export has the following properties:

Property Type Description
minivanExportId int Read-only; Unique identifier for a MiniVAN Export
name string The name given to the list when it was exported to MiniVAN
databaseMode int Whether the export exists in VoterFile mode (0) or MyCampaign mode (1)
dateCreated date The date the export was created
createdBy object An object containing a userId property indicating the ID of the VAN User who created the export
canvassers array An array of objects containing a canvasserId property indicating the ID of the VAN User who received the export and canvassed the list
eventSignups array List of Event Signups to which this list has been assigned.

Please note that the canvassers for an export (indicated by the canvasserId property) may be different than the person or people whose event signup(s) the export is attached to (as indicated in eventSignups). That may result from data collection proactices that differ across clients, field offices, etc.

GET/minivanExports

Get all available MiniVAN Exports
Description

Use this endpoint to retrieve all available MiniVAN Exports.

Request

This endpoint accepts standard pagination parameters and returns a standard paginated response.

By default, this endpoint returns 10 records per request. A maximum of 50 records per request is allowed via the $top parameter.

Valid expansion properties are: eventSignups and canvassers. Note that the number of $expand sections requested may impact the speed with which this endpoint will respond.

The endpoint takes the following optional filter parameters:

Parameter Location Type Description
generatedAfter query date Filter result set by exports generated after the specified date.
generatedBefore query date Filter result set by exports generated before the specified date.
createdBy query int Filters result set ID of the VAN user who created the exports.
name query string Filters result set by exports with the specified name
hasSignup query bool Optional; if true, shows only exports which are attached to event signups; if false, shows only exports which are not attached to event signups. If omitted, does not filter by signup attachment at all.
$expand query string Optional; comma delimited list of expansion properties: eventSignups, canvassers
GET /minivanExports?generatedAfter=2012-10-01&generatedBefore=2012-11-01&createdBy=123&name=GOTV&hasSignup=true&$expand=eventSignups,canvassers
Response

A paginated list of MiniVAN Export objects.

GET/minivanExports/{minivanExportId}

Get MiniVAN Export
Description

Use this endpoint to get full details for a MiniVAN Export

Request

The request has no parameters

GET /minivanExports/888777
Response

MiniVAN Export

Custom Fields

Overview

A Custom Field represents structured data about a person or other object in VAN, configured by a VAN user. A Contacts Custom Field (which is the only type of custom field available via the API) is a Custom Field applied to People. Note: Custom Fields may only be assigned to People in MyCampaign mode; assignment is not available in VoterFile mode.

Custom Fields are collected into Groups for better organization and administration. For example, a committee which works heavily with college students might have a Custom Fields Group called "Student Custom Field Group", with fields such as "Selected field of study", "Name of high school", etc.

Every Custom Field has a data type, which indicates what kind of data will be accepted for that custom field. The data types, and restrictions on the data available, are as follows:

  • Boolean: accepts only "true" or "false"
  • Selection: accepts only one of the available values belonging to the custom field
  • Text: accepts any text, limited by the maximum number of characters stipulated in the custom field
  • Date: accepts only dates in the format YYYY-MM-DD
  • Number: accepts numeric values, limited by the maximum number of characters stipulated in the custom field
  • Money: accepts currency amounts

Custom Fields of type Selection may have parents to indicate hierarchies within the available values. The parent of a Custom Field must also be a Selection field, and is usually used to indicate a higher level of groupings for the available values. If a Custom Field has a parent, then each of its available values also has a parent, and each parent is an available value in the parent custom field. For example, if one custom field indicates "Field of study" for college students, then its parent custom field might indicate "Department", and their available values might be organized as follows:

  • Physical sciences (available value for Department)
    • Biology (available value for Field of study; parent available value is Physical sciences)
    • Chemistry (available value for Field of study; parent available value is Physical sciences)
  • Liberal arts (available value for Department)
    • History (available value for Field of study; parent available value is Liberal arts)
    • English (available value for Field of study; parent available value is Liberal arts)

Common Models

  • CustomFieldTypes:
    • B = Boolean (Checkbox)
    • S = Selection (Dropdown)
    • T = Text
    • D = Date
    • N = Number
    • M = Money (Currency)
{
    "customFieldId": 157,
    "customFieldParentId": null,
    "customFieldName": "Education level",
    "customFieldGroupId": 52,
    "customFieldGroupName": "Education",
    "customFieldTypeId": "S",
    "isEditable": true,
    "maxTextboxCharacters": null,
    "availableValues": [
      {
        "id": 1,
        "name": "High School diploma",
        "parentValueId": null
      },
      {
        "id": 2,
        "name": "College degree",
        "parentValueId": null
      },
      {
        "id": 3,
        "name": "Postgraduate degree",
        "parentValueId": null
      },
      {
        "id": 4,
        "name": "Doctorate",
        "parentValueId": null
      }
    ]
}
Custom Field
Property Type Description
customFieldId int Unique identifier for a Custom Field in this context
customFieldParentId int? Identifies a Selection’s parent (Only applies to hierarchical Selections)
customFieldName string The name for the Custom Field, no longer than 255 characters
customFieldGroupId int Unique identifier for the Custom Field Group to which this Custom Field belongs
customFieldGroupName string The name of the Custom Field Group to which this Custom Field belongs, no longer than 60 characters
customFieldTypeId string A one character identifier of the Custom Field type
isEditable boolean Indicates whether or not the value assigned to the Custom Field can be changed
maxTextboxCharacters int? The maximum number of characters allowed in the text field. (Only applies to Text or Number fields)
availableValues array An array of available values. (Only applies to Selections)
AvailableValue
Property Type Description
id int The value of the Selection option
name string The text of the Selection option, no longer than 100 characters
parentValueId int? The id of the the Selection option in the Custom Field’s parent Selection (Only applies to hierarchical Selections)

GET/customFields

Retrieve available Custom Fields
Description

Use this endpoint to retrieve all Custom Fields that are available in the current context.

Request

This endpoint has no parameters.

Response

This endpoint responds with all Custom Fields that are available in the current context. This is an example response.

[
  {
    "customFieldId": 157,
    "customFieldParentId": null,
    "customFieldName": "Education level",
    "customFieldGroupId": 52,
    "customFieldGroupName": "Education",
    "customFieldTypeId": "S",
    "isEditable": true,
    "maxTextboxCharacters": null,
    "availableValues": [
      {
        "id": 1,
        "name": "High School diploma",
        "parentValueId": null
      },
      {
        "id": 2,
        "name": "College degree",
        "parentValueId": null
      },
      {
        "id": 3,
        "name": "Postgraduate degree",
        "parentValueId": null
      },
      {
        "id": 4,
        "name": "Doctorate",
        "parentValueId": null
      }
    ]
  },
  {
    "customFieldId": 205,
    "customFieldParentId": null,
    "customFieldName": "Has student loans",
    "customFieldGroupId": 55,
    "customFieldGroupName": "College Student Organizing",
    "customFieldTypeId": "B",
    "isEditable": true,
    "maxTextboxCharacters": null,
    "availableValues": null
  },
  {
    "customFieldId": 206,
    "customFieldParentId": null,
    "customFieldName": "Stipend amount",
    "customFieldGroupId": 55,
    "customFieldGroupName": "College Student Organizing",
    "customFieldTypeId": "M",
    "isEditable": false,
    "maxTextboxCharacters": null,
    "availableValues": null
  },
  {
    "customFieldId": 207,
    "customFieldParentId": null,
    "customFieldName": "Graduation date",
    "customFieldGroupId": 55,
    "customFieldGroupName": "College Student Organizing",
    "customFieldTypeId": "D",
    "isEditable": true,
    "maxTextboxCharacters": null,
    "availableValues": null
  },
  {
    "customFieldId": 208,
    "customFieldParentId": null,
    "customFieldName": "Department of study",
    "customFieldGroupId": 55,
    "customFieldGroupName": "College Student Organizing",
    "customFieldTypeId": "S",
    "isEditable": true,
    "maxTextboxCharacters": null,
    "availableValues": [
      {
        "id": 1,
        "name": "Physical sciences",
        "parentValueId": null
      },
      {
        "id": 2,
        "name": "Liberal arts",
        "parentValueId": null
      }
    ]
  },
  {
    "customFieldId": 209,
    "customFieldParentId": 208,
    "customFieldName": "Field of study",
    "customFieldGroupId": 55,
    "customFieldGroupName": "College Student Organizing",
    "customFieldTypeId": "S",
    "isEditable": true,
    "maxTextboxCharacters": null,
    "availableValues": [
      {
        "id": 1,
        "name": "Biology",
        "parentValueId": 1
      },
      {
        "id": 2,
        "name": "Chemistry",
        "parentValueId": 1
      }
      {
        "id": 1,
        "name": "History",
        "parentValueId": 2
      },
      {
        "id": 2,
        "name": "English",
        "parentValueId": 2
      }
    ]
  },
  {
    "customFieldId": 210,
    "customFieldParentId": null,
    "customFieldName": "Number of semesters of study remaining",
    "customFieldGroupId": 55,
    "customFieldGroupName": "College Student Organizing",
    "customFieldTypeId": "N",
    "isEditable": true,
    "maxTextboxCharacters": null,
    "availableValues": null
  },
  {
    "customFieldId": 211,
    "customFieldParentId": null,
    "customFieldName": "Name of high school",
    "customFieldGroupId": 55,
    "customFieldGroupName": "College Student Organizing",
    "customFieldTypeId": "T",
    "isEditable": true,
    "maxTextboxCharacters": 75,
    "availableValues": null
  }
]

GET/customFields/{customFieldId}

Retrieve a specific Custom Field
Description

Use this endpoint to retrieve information about a specific Custom Field available in the current context.

Request

This endpoint takes the following parameter:

Parameter Location Type Description
customFieldId route int Unique identifier for a specific Custom Field.
GET /customFields/165
Response

A standard Custom Field object, if found.

File-Loading Jobs

Overview

A File-Loading Job is a long-running process which is to be completed asynchronously, followed by a notification to a third party once the job completes. The first step in such a job is to retrieve a file, usually by FTP, and then load it into the system so that it may be processed via a series of actions. Currently the only type of action available is for score updates, but others may be added in the future.

POST/fileLoadingJobs

Create a file-loading job
Description

Initiates a file-loading job by specifying the URL for a zipped CSV file, containing data to be loaded, and the action(s) to be taken on it.

Request
File-Loading Job
Property Type Description
description string Required; A description of the job, to be included in notifications (whether via email or webhook). Maximum length is 255 characters. No HTML or HTML special character syntax. More precisely, input must not match this regex: [\<>]+|&#
file object Required; A File object which describes the source file and columns to be acted on.
actions array Required; An array of Action objects, each defining an action to be taken. Currently only score-loading actions are available.
listeners array Optional; An optional array of one or two Listener objects indicating means of notification, email or webhook. Only one of each type can be specified.
File
Property Type Description
fileName string Required; Name of the csv-formatted file within the zip file accessible by sourceUrl (e.g., MyScoreResults.csv).
hasHeader bool Optional; Indicates whether the first row of the source file should be skipped.
sourceUrl string Required; URL at which a zip file containing the source file to be loaded can be accessed. The following URL schemes (“protocols”) are supported: SFTP, FTP, FTPS, HTTPS, HTTP. If authentication is required, the username and password should be included in the URL (e.g., ftp://user:password@foo.bar.us/zz_my_camp_score.zip).
columnDelimiter string Optional; Character that separates each each column; one of: Csv → , separated values, Tab → Tab separated values, Pipe → | separated values
columns array Required; An ordered array of Column objects, describing each column of the source file (from left to right). At least one column is required.
Column
Property Type Description
name string Required; A column’s unique name that can be referenced in actions (e.g., VanID).
Action
Property Type Description
actionType string Required; An action type that must be available to the target context. The only supported action type is: score → Creates a Score Update job which can be approved for loading via the scoreUpdate endpoint. All properties are required.
personIdColumn string Required; The source file column name containing person identifiers.
personIdType string Required; A type of person identifier that is already available within the target context.; one of: VANID → Always available, DWID → Only available in select VAN instances
scoreColumn string Required; The source file column name containing positive integer score values.
scoreId int Required; The unique identifier of a score available within the target context. The score must be a Range score, not a Value score.
Listener
Property Type Description
type string Required; A method of notification: EMAIL or URL.; one of: EMAIL → Indicates that ‘value’ is an email address to which the details of a job’s success or failure should be sent., URL → Indicates that ‘value’ is a URL to which the details of a job’s success or failure will be posted. The results will be a JSON object sent via POST and will be formatted like a Notification object.
value string Required; A valid email address or URL (e.g., ‘datateam@mydomain.com’, ‘http://mydomain.com/vanjobs/notify/myInternalJobId‘)
Notification

The object which is sent by POST to a webhook registered when the job is completed, if applicable.

Property Type Description
description string The job description specified when creating the job.
message string Detailed description of a job’s success (or failure)
POST /fileLoadingJobs
{
    "description": "Load habberdasher score",
    "file": {
        "columnDelimiter": "Csv",
        "columns": [
            {
                "name": "hatWearerId"
            },
            {
                "name": "hatWearingScore"
            }
        ],
        "fileName": "haberdashery.csv",
        "hasHeader": true,
        "sourceUrl": "ftp://keep:yourHatOn@ftp.headpieces.example.org/haberdasher.csv.zip"
    },
    "actions": [
        {
            "actionType": "score",
            "personIdColumn": "hatWearerId",
            "personIdType": "VANID",
            "scoreColumn": "hatWearingScore",
            "scoreId": 112233
        }
    ],
    "listeners": [
        {
            "type": "URL",
            "value": "https://haberdashery.example.org/listener"
        },
        {
            "type": "EMAIL",
            "value": "support@haberdashery.com"
        }
    ]
}
Response
{
    "jobId": 998877
}

Once the job is processed, the following data will be sent to the registered webhook:

POST https://haberdashery.example.org/listener
{
    "description": "Load habberdasher score",
    "message": "success"
}

Scores

Overview

A range score offers a method of indicating a probability that an individual has some attribute or another. Range scores have minimum and maximum values, which typically (but not necessarily) are 0.0 and 100.0, with higher score values usually indicating greater probability that an individual has a certain attribute.

GET/scores

Get scores
Description

Get all available range scores

Request
GET /scores
Response
{
  "items": [
    {
      "scoreId": 123,
      "name": "Haberdashery score",
      "shortName": "HATS",
      "description": "How many hats does someone own",
      "minValue": 1.00,
      "maxValue": 10.00
    },
    {
      "scoreId": 555,
      "name": "Hat disposition",
      "shortName": "HATD",
      "description": "Likelihood of wanting more hats",
      "minValue": 1.00,
      "maxValue": 100.00
    }
  ],
  "nextPageLink": null,
  "count": 2
}

GET/scores/{scoreId}

Get a score
Description

Retrieve a single range score

Request
Parameter Location Type Description
scoreId route int Required; Unique identifier of the score to be retrieved
GET /scores/123
Response
{
  "scoreId": 123,
  "name": "Haberdashery score",
  "shortName": "HATS",
  "description": "Likelihood of owning a hat",
  "minValue": 1.00,
  "maxValue": 10.00
}

Score Updates

Overview

A Score Update indicates the status of a Job that is intended to apply Scores to People - including both the system’s progress in processing that score, and statistics that provide a high-level overview of the changes that the Job in question will trigger. Because of the possibility of broadly destructive mistakes made during a Job, Score Updates must be changed to an approval or rejection state, once the statistics in question have been reviewed.

GET/scoreUpdates

Get Score Updates
Description

Get all available Score Updates, optionally filtered by search parameters.

Request
Parameter Location Type Description
createdBefore query date Optional; Filters Score Updates to those created before (and not including) a given date (in the format yyyy-mm-dd)
createdAfter query date Optional; Filters Score Updates to those created after (and not including) a given date (in the format yyyy-mm-dd)
scoreId query int Optional; Filters Score Updates to those of the given score
GET /scoreUpdates?createdBefore=2015-12-31&createdAfter=2015-01-01&scoreId=999
Response
{
  "items": [
    {
      "scoreUpdateId": 1888,
      "score": {
        "scoreId": 888,
        "name": "Baseball cap wearer",
        "shortName": "Likelihood of wearing a baseball cap",
        "description": "Indicates our best guess as to whether this voter wears a baseball cap",
        "minValue": 1.00,
        "maxValue": 100.00,
      },
      "updateStatistics": {
        "totalRows": 100,
        "duplicateRows": 3,
        "matchedRows": 100,
        "matchPercent": 100.0,
        "increasedBy": 100,
        "decreasedBy": 0,
        "nulledOut": 0,
        "added": 0,
        "outOfRange": 0,
        "badValues": 1,
        "maxValue": 10.0,
        "minValue": 90.00,
        "averageValue": 50.0,
        "medianValue": 47.0
      },
      "loadStatus": "Completed",
      "dateProcessed": "2015-08-23T02:00:00Z"
    },
    {
      "scoreUpdateId": 1999,
      "score": {
        "scoreId": 999,
        "name": "Fedora wearer",
        "shortName": "Likelihood of wearing a fedora",
        "description": "Indicates our best guess as to whether this voter wears a fedora",
        "minValue": 1.00,
        "maxValue": 100.00,
      },
      "updateStatistics": {
        "totalRows": 50,
        "duplicateRows": 0,
        "matchedRows": 50,
        "matchPercent": 100.0,
        "increasedBy": 6,
        "decreasedBy": 43,
        "nulledOut": 0,
        "added": 0,
        "outOfRange": 0,
        "badValues": 0,
        "maxValue": 14.00,
        "minValue": 34.00,
        "averageValue": 24.0,
        "medianValue": 24.0
      },
      "loadStatus": "Canceled",
      "dateProcessed": null
    }
  ],
  "nextPageLink": null,
  "count": 2
}

GET/scoreUpdates/{scoreUpdateId}

Get Score Update
Description

Retrieve a single score update

Request
Parameter Location Type Description
scoreUpdateId route int Required; Unique identifier of the score update to be retrieved
GET /scoreUpdates/1888
Response
{
  "scoreUpdateId": 1888,
  "score": {
    "scoreId": 888,
    "name": "Baseball cap wearer",
    "shortName": "Likelihood of wearing a baseball cap",
    "description": "Indicates our best guess as to whether this voter wears a baseball cap",
    "minValue": 1.00,
    "maxValue": 100.00,
  },
  "updateStatistics": {
    "totalRows": 100,
    "duplicateRows": 3,
    "matchedRows": 100,
    "matchPercent": 100.0,
    "increasedBy": 100,
    "decreasedBy": 0,
    "nulledOut": 0,
    "added": 0,
    "outOfRange": 0,
    "badValues": 1,
    "maxValue": 10.0,
    "minValue": 90.00,
    "averageValue": 50.0,
    "medianValue": 47.0
  },
  "loadStatus": "Completed",
  "dateProcessed": "2015-08-23T02:00:00Z"
}

PATCH/scoreUpdates/{scoreUpdateId}

Approve or Reject a Score
Description

Changes the status of a score (e.g., from PendingApproval to Approved). Score updates that are approved, are applied at off-peak hours.

Request
Parameter Location Type Description
scoreUpdateId route int Required; Unique identifier of the score update to be changed
Score Status
Property Type Description
loadStatus string Required; The new status for a score update; one of: PendingApproval → Score updates in the pending state will not be applied, Approved → Approves the score update for application during off-peak hours, Disapproved → Explicitly indicates the score update should not be applied (e.g., because the load statistics indicate an issue with a source file), Canceled → Cancel the score update process (does not stop anything that is currently in process, behaves the same as Disapproved

The following status transitions are supported:

  • Unknown, PendingApproval, Approved, DisapprovedCanceled
  • PendingApproval, DisapprovedApproved
  • PendingApproval, ApprovedDisapproved
  • Approved, DisapprovedPendingApproval

No other status transitions are allowed. Once a Score update is approved, the system will automatically process the score update during off-peak hours; the status will change to Completed after processing finishes.

PATCH /scoreUpdates/1888
{
    "loadStatus": "Approved"
}
Response
204 No Content

Reported Demographics

Overview

A reported demographic is a category which a person chooses to identify with, and which is subsequently applied by a user in the front end or via an API call. Demographics include race, ethnicity, and language preference. These services indicate the demographic options which are available for use in describing a person within the current context.

GET/reportedRaces

Retrieve available Reported Races
Description

Use this endpoint to retrieve all Reported Races that are available in the current context.

Request

This endpoint accepts standard pagination parameters.

GET /reportedRaces?$top=3&$skip=1
Response

A paginated list of options for reporting race in the current context.

{
  "items": [
    {
      "reportedRaceId": 2,
      "reportedRaceName": "Black or African American"
    },
    {
      "reportedRaceId": 3,
      "reportedRaceName": "Caucasian or White"
    },
    {
      "reportedRaceId": 4,
      "reportedRaceName": "Native American"
    }
  ],
  "nextPageLink": "https://api.securevan.com/v4/reportedRaces?$top=3&$skip=4",
  "count": 7
}

GET/reportedEthnicities

Retrieve available Reported Ethnicities
Description

Use this endpoint to retrieve all Reported Ethnicities that are available in the current context.

Request

This endpoint accepts standard pagination parameters.

GET /reportedEthnicities?$top=3&$skip=1
Response

A paginated list of options for reporting ethnicity in the current context.

{
  "items": [
    {
      "reportedEthnicityId": 2,
      "reportedEthnicityName": "Arab"
    },
    {
      "reportedEthnicityId": 3,
      "reportedEthnicityName": "Asian Indian"
    },
    {
      "reportedEthnicityId": 4,
      "reportedEthnicityName": "Bangladeshi"
    }
  ],
  "nextPageLink": "https://api.securevan.com/v4/reportedEthnicities?$top=3&$skip=4",
  "count": 20
}

GET/reportedLanguagePreferences

Retrieve available Reported Language Preferences
Description

Use this endpoint to retrieve all Reported Language Preferences that are available in the current context.

Request

This endpoint accepts standard pagination parameters.

GET /reportedLanguagePreferences?$top=3&$skip=1
Response

A paginated list of options for reporting language preference in the current context.

{
  "items": [
    {
      "reportedLanguagePreferenceId": 2,
      "reportedLanguagePreferenceName": "Cantonese"
    },
    {
      "reportedLanguagePreferenceId": 3,
      "reportedLanguagePreferenceName": "English"
    },
    {
      "reportedLanguagePreferenceId": 4,
      "reportedLanguagePreferenceName": "French"
    }
  ],
  "nextPageLink": "https://api.securevan.com/v4/reportedLanguagePreferences?$top=3&$skip=4",
  "count": 20
}

Contributions

Overview

A Contribution is a record of a person’s monetary gift. They must be linked to both the contact that contributed, and the designation corresponding to the contribution.

Contributions can be associated with a pledge, attributed to other contacts, and have codes applied to them.

Common Models

The following is an example of a contribution.

{
    "contact": {
        "vanId": 10005165
    },
    "designation": {
        "designationId": 18754,
    },
    "dateReceived": "2013-12-25T12:23:00Z",
    "amount": "12.34",
    "status": "Settled", 
    "paymentType": "Check",
    "bankAccount": "PNC Bank Account 1",
    "depositDate": "2013-12-28",
    "depositNumber": 3,
    "checkDate": "2013-12-25",
    "checkNumber": "1222 123",
    "contactAttributions": [
        { "vanId": 303 },
        { "vanId": 302 }
    ],
    "onlineReferenceNumber": "1230230423", 
    "pledge": {
        "pledgeId": 1035
    }, 
    "codes": [
        { "codeId": 12345 },
        { "codeId": 12347 },
    ],
    "directMarketingCode": "Excelsior Consulting",
    "dateThanked": "2013-12-30",
    "notes": "Processed as part of the Christmas Fundraiser"
}

The following is an overview of the Contribution object and its related objects. In some cases, the related object has a dedicated endpoint. In these cases, a link to those endpoints is provided.

Contribution

The required properties are contact, designation, dateReceived, amount, status, and paymentType.

Property Type Description
contact object The Person who contributed
designation object The financial entity which will receive this contribution.
dateReceived datetime The date and time of this contribution; must occur before the time of the API call.
amount decimal The amount of the contribution. Non-positive values, and values that have more than 2 digits after the decimal point, will not be accepted.
status string The current status of the contribution: Declined, Pending, or Settled.
paymentType string A string representing the method of payment. See below for valid values of Payment Type.
bankAccount string The name of the bank account.
depositDate date The date of the deposit.
depositNumber string The number of the deposit.
checkDate date The date of the check.
checkNumber string The number of the check.
contactAttributions array An array of People attributed to the contribution. Represents contacts who acted as fundraisers, rather than contributors.
onlineReferenceNumber string An alphanumeric code used to identify additional information about a contribution, usually indicating a transaction ID from the contribution processor.
pledge object The associated Pledge object.
codes array A list of Codes to apply to the contribution.
directMarketingCode string A direct marketing code.
dateThanked date The date the contributor was thanked.
notes string A note describing the contribution.
Designation
Property Type Description
designationId int The id of the designation which receives this contribution.
Pledge
Property Type Description
pledgeId int The pledge id of the associated pledge.
Payment Type

One of

  • Check
  • MoneyOrder
  • Cash
  • CreditCard
  • InKind
  • Unknown
  • ElectronicFundsTransfer
  • ElectronicPaySystem
  • PayPal

POST/contributions

Create a new contribution
Description

Use this endpoint to create a new contribution with the properties provided in the request body.

Request

The body of the request should be a standard Contribution object.

Response

If successful, the endpoint responds with HTTP Status Code 201 Created and the integer ID of the created Contribution in the response body.

If any of the specified ids (vanId, pledgeId, or codeId) are not accessible in the current context (e.g., the associated api user does not have access to the person), the response will be considered invalid.

Designations

Overview

A designation is the representation of a compliance report inside one VAN committee. Calls to the designation endpoint retrieve a list of designations including the logical name and id for those designations. Contributions can be assigned designations by id.

Common Models

The following is an example of designation

    {
        "designationId": 123456789,
        "name": "Jane for Congress Committee"
    }

The following is an overview of the Designation object.

Designation

Available properties

Property Type Description
designationId int Unique identifier for a Designation in this context.
name string A name for this designation

GET/designations

Gets a list of designations
Description

Use this endpoint to get designation IDs and names

Request

This endpoint takes no parameters

Response

Returns an object with a single items property which is an array of standard Designation objects

{
    "items" : [
        {
          "designationId": 123456789,
          "name": "Jane for Congress Committee"
        },
        {
          "designationId": 123456790,
          "name": "Jane Smith Progressive Leadership PAC"
        }
    ]
}