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.
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
.
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.
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.
See the Getting Started section.
Data in our system is divided into four dimensions.
Instances are a group of databases which share a common national data set. Well-known instances include VoteBuilder, America Votes VAN, Labor Activation Network, and SmartVAN. While it is possible for certain kinds of data to be shared between one Database and another, across Database Modes, or between one Committee and another, data may not be shared across Instances.
Databases are the sharding mechanism for data about people. For many Instances, people data is sharded by states, meaning that campaigns and organizations in one state do not share data with campaigns and organizations in another state.
Database Modes offer two different sets of rules for sourcing and managing person data within a Database. My Voters mode contains contains data about voters gathered from official voting rolls; it is not possible to create new person records in My Voters mode. My Campaign mode contains data about an organization’s supporters, and new person records may be created in My Campaign mode. While many Databases have both My Voters and My Campaign modes available, some Databases have only My Campaign mode, or only My Voters mode. It is possible to annotate a Person record in both My Voters and My Campaign mode.
Committees are the tenanting mechanism for separating data owned by different organizations. As a general rule, the data owned by one Committee may not be viewed by another Committee. However, it is possible for Committees to share certain kinds of data with one another if desired. Committees may exist in a single Database, as would be the case for a local or statewide electoral campaign, or they may exist in multiple Databases, as would be the case for a national organization.
Users are the primary component of the security model, and indicate a person or entity who has permission to interact with the system.
Permissions allow Users to carry out certain functions within the system, for example, Create and Edit Events. Some Permissions are available in My Voters mode only, or in My Campaign mode only. For example, because the Events feature is available in My Campaign mode only, the Create and Edit Events Permission is also available in My Campaign mode only.
User Profiles indicate a series of Permissions. For each Database and Database Mode that a User may access, that User has a single User Profile which governs the functions the User is allowed to perform within that Database and Database Mode combination.
Every API key gives a single User the ability to access data within a single Instance, Database, and Committee only. In many cases, an API key will provide access to both My Voters and My Campaign mode. However, no API key will provide access to multiple Databases or Committees simultaneously.
Every API service is connected to a Permission, and an API key’s ability to access that service is determined by whether or not the API key’s User has the relevant Permission in the User Profile. In some cases, additional Permissions control the way in which a given API service operates - for example, there are some Expand Sections in the GET /people/{vanId} service which require special Permissions for access.
Authorized API key request reviewers may optionally specify a date at which the API key’s ability to make calls expires. We recommend setting an expiration date for most keys. If an API key has an expiration date, it will be discoverable in-app via the API Integrations page, or via an introspection API call.
Please note that some clients may require API keys to have an expiration date. Developers and users should work with client admins to ensure keys are regenerated prior to expiration.
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"
}
]
}
Failed requests count against your overall API use quota. It’s recommended you employ an Exponential Backoff strategy for handling temporary error scenarios.
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.
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'"
}
]
}
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
}
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.
If you’re unsure which endpoint to use, contact NGP VAN API support.
If it’s necessary to record data about the activity of users in other systems, the API may be used to create records known as Public Users in My Campaign mode. Public Users are created using the identifiers
property in the POST /people/findOrCreate request, provided the type
property is configured as a Public User identifier. Please contact us to configure an identifer type for use in the Public User system.
For example, a Public User may be created as follows:
POST /people/findOrCreate
{
"firstName": "Becky",
"lastName": "Smith",
"identifiers": [
{
"type": "AcmeCRMId",
"externalId": "becky.smith"
}
]
}
Once a Public User has been created, the user should be indicated by providing the type
and externalId
values as Base64-encoded values in the X-NGPVAN-User-Type
and X-NGPVAN-User-Token
headers, respectively.
Now the Public User created above may be specified as the actor on an API call as follows:
X-NGPVAN-User-Type: QWNtZUNSTUlk
X-NGPVAN-User-Token: YmVja3kuc21pdGg=
In this case, the type “AcmeCRMId” has been Base64-encoded, yielding the Public User Type “QWNtZUNSTUlk”, and the identifier “becky.smith” has been Base64-encoded, yielding the Public User Token “YmVja3kuc21pdGg=”.
As a result, when the API request is received, additional information is recorded about the Public User, indicating the person who triggered the request. For some API requests, providing the Public User headers in this manner will provide better visibility as to which person took an action. For example, use of the Public User system makes it easy to see which external user contacted a voter, when viewing contact history.
An introspection endpoint is available, if you need information about the API key you are using. The route returns a Paginated List of API keys available, with only one element in the list.
GET /apiKeyProfiles
200 OK
{
"items": [
{
"databaseName": "SmartVAN Massachusetts",
"hasMyVoters": true,
"hasMyCampaign": true,
"committeeName": "People for Good",
"apiKeyTypeName": "Custom Integration",
"keyReference": "1234",
"userFirstName": "peopleforgood",
"userLastName": "api",
"username": "peopleforgood.api"
}
],
"nextPageLink": null,
"count": 1
}
The easiest way to get started is to send a sample request to the POST /echoes
route. This endpoint takes a message and repeats it back, with a datetime stamp:
POST /echoes
{
"message": "Hello, world"
}
200 OK
{
"message": "Hello, world",
"dateSent": "2017-01-01T00:00:00Z",
"delayInMilliseconds": null
}
You can simulate a slow request with POST /echoes
, by using the delayInMilliseconds
parameter. This can be helpful in testing responses to slow requests. delayInMilliseconds
defaults to 0, and can be at most 30,000 milliseconds (30 seconds).
POST /echoes
{
"message": "Hello, world, you seem sleepy this morning",
"delayInMilliseconds": 1000
}
200 OK
{
"message": "Hello, world, you seem sleepy this morning",
"dateSent": "2017-01-01T00:00:00Z",
"delayInMilliseconds": 1000
}
The following are three basic code samples for interacting with this API using cURL, NodeJS, and C#. Note that in each case we are using a fictional API key (7c9e6679-7425-40de-944b-e07fc1f90ae7
) and that the call is being placed in MyCampaign mode. You will need to replace that key with your own before running the code, and will need to use "0"
instead of "1"
to place the call in VoterFile mode.
curl -H "Content-type: application/json" \
--user "acmeCrmProduct:7c9e6679-7425-40de-944b-e07fc1f90ae7|1" \
-X POST \
--data '{ "message": "Hello, world" }' \
https://api.securevan.com/v4/echoes
var request = require('request');
var username = 'acmeCrmProduct';
var apiKey = '7c9e6679-7425-40de-944b-e07fc1f90ae7';
var dbMode = '1';
var password = apiKey + '|' + dbMode;
var options = {
headers: { 'Content-type' : 'application/json' },
auth: {
user: username,
password: password
},
json: {
"message": "Hello, world"
},
uri: 'https://api.securevan.com/v4/echoes'
};
request.post(options, function (err, res, body) {
if (err) {
console.dir(err);
return;
}
console.dir(res.statusCode);
console.dir(body);
});
string username = "acmeCrmProduct";
string apiKey = "7c9e6679-7425-40de-e07fc1f90ae7";
string dbMode = "1";
string password = apiKey + "|" + dbMode;
string url = "https://api.securevan.com/v4/echoes";
object data = new {
message = "Hello, world"
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
var content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
using(var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization",
"Basic " + Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", username, password))));
var response = client.PostAsync(url, content).Result;
}
We’ve built a public Postman Collection to help you get started with our API.
On the Auth
tab for the request, set up your authentication using Basic Auth. (You can also set one key for the entire collection by going to Edit
➡ Authorization
, and then set the individual requests as Inherit Auth From Parent
.)
Begin making API calls!
In the collection, you will notice that some calls contain colons (:
) in the URL. For example, https://api.securevan.com/v4/people/:personIdType::personId
. Each of these terms preceded by a colon is something you should replace in your call. In this call, you would replace :personIdType
and :personId
with the information you need in the call. Note that colons can also appear in the URL! The colon immediately after :personIdType
is part of the URL and should not be replaced.
A common scenario in using the API is to add a supporter’s name and contact information to a My Campaign database. Often it’s also necessary to annotate the supporter record, e.g. to indicate that the supporter wants to volunteer, is interested in a particular issue, etc.
To create a supporter record in My Campaign, use the POST /people/findOrCreate route. This example illustrates creating the supporter record with an email address and zip code:
curl -H "Content-type: application/json" \
--user "awesomeSauceApp:7c9e6679-7425-40de-944b-e07fc1f90ae7|1" \
-X POST \
--data '{ "firstName": "Leslie", "lastName": "Knope", "emails": [ { "email": "knope@citycouncil.pawnee.in.example.org" } ], "addresses": [ { "zipOrPostalCode": "46064" } ] }' \
https://api.securevan.com/v4/people/findOrCreate
The API response will look something like this:
{
"vanId": 101202303,
"status": "Matched"
}
The vanId
property may now be used to provide additional data about this supporter, in conjunction with POST /people/{vanId}/canvassResponses. For example, if Activist Code 1234
indicates that the supporter wishes to volunteer, then the supporter record may be annotated as follows:
curl -H "Content-type: application/json" \
--user "awesomeSauceApp:7c9e6679-7425-40de-944b-e07fc1f90ae7|1" \
-X POST \
--data '{ "responses": [ { "activistCodeId": 1234, "action": "Apply", "type": "ActivistCode" } ] }' \
https://api.securevan.com/v4/people/101202303/canvassResponses
Note that in the above example, the vanId
property from the response to the first API call (that is, 101202303
) was used to form the route for the second API call (that is, https://api.securevan.com/v4/people/101202303/canvassResponses
).
The full list of Activist Codes which may be applied to a Person are available at GET /activistCodes. This list will be different for each API key, and may provide different responses in My Voters and My Campaign mode. Similarly, it is also possible to apply Survey Question Responses to a Person; the full list of Survey Questions are available at GET /surveyQuestions.
Event signup is crucial to the organizing strategy of many organizations. Providing supporters with tools to sign up for an event online is a common feature in many web sites and applications.
To sign up a supporter for an Event, it is first necessary to Add a supporter. The vanId
of the supporter is used to create the Event RSVP.
The other data needed for an Event Signup includes:
Most of these values are available in the GET /events/{eventId} route. For example, to get the details for Event 777
:
curl -H "Content-type: application/json" \
--user "awesomeSauceApp:7c9e6679-7425-40de-944b-e07fc1f90ae7|1" \
-X GET \
"https://api.securevan.com/v4/events/777?\$expand=locations,shifts,roles"
Note that the request URL (https://api.securevan.com/v4/events/777?$expand=locations,shifts,roles
) is enclosed in quotes, and the $expand
parameter is preceded with a backslash (\
) to avoid unintentional shell expansion.
The response will look something like this:
{
"eventId": 777,
"name": "Future of Lot 48",
"shortName": "Lot48",
"description": "We will discuss what to do with Lot 48.",
"startDate": "2018-02-14T19:00:00-05:00",
"endDate": "2018-02-14T21:00:00-05:00",
"eventType": {
"eventTypeId": 555,
"name": "Public hearing"
},
"locations": [
{
"locationId": 333,
"name": "Sweetums Factory",
"displayName": "Sweetums Factory, 123 Sugar StPendleton, IN 46064 ",
"address": {
"addressLine1": "123 Sugar St",
"city": "Pendleton",
"stateOrProvince": "IN",
"zipOrPostalCode": "46064",
"countryCode": "US",
},
}
],
"shifts": [
{
"eventShiftId": 111,
"name": "Single Shift",
"startTime": "2018-02-14T19:00:00-05:00",
"endTime": "2018-02-14T21:00:00-05:00"
}
],
"roles": [
{
"roleId": 444,
"name": "Disgruntled citizen",
}
],
}
To determine which Statuses are available for the Event Signup, us GET /events/types/{eventTypeId} to retrieve details on the Event Type - in this case, 555
:
curl -H "Content-type: application/json" \
--user "awesomesauceApp:7c9e6679-7425-40de-944b-e07fc1f90ae|1" \
-X GET \
"https://api.securevan.com/v4/events/types/555"
The response will look something like this:
{
"eventTypeId": 555,
"name": "Public hearing",
"roles": [
{
"roleId": 444,
"name": "Disgruntled citizen"
}
],
"statuses": [
{
"statusId": 1,
"name": "Scheduled"
},
{
"statusId": 15,
"name": "Walk In"
}
]
}
From these API responses, we can see that the following Event Signup options are valid:
777
333
(“Sweetums Factory”)444
(“Disgruntled citizen”)111
(7pm - 9pm)1
(“Scheduled”) or 15
(“Walk in”)Using this information, we can now signup a supporter for this event. The following example uses the POST /signups route to create an Event Signup in the Event indicated above, for the Person created in the Add a supporter section:
curl -H "Content-type: application/json" \
--user "awesomeSauceApp:7c9e6679-7425-40de-944b-e07fc1f90ae|1" \
-X POST \
--data '{ "person": { "vanId": 101202303 }, "event": { "eventId": 777 }, "shift": { "eventShiftId": 111 }, "role": { "roleId": 444 }, "status": { "statusId": 1 }, "location": { "locationId": 333 } }' \
https://api.securevan.com/v4/signups
The response will be a simple integer:
4848
This is the Event Signup ID, which may be used to alter the signup in the future, using PUT /signups/{eventSignupId}. The Event Signup may also be deleted using DELETE /signups/{eventSignupId}.
This example illustrates a simple Event Signup, because there is only one Location, one Role, and one Shift. If multiple options were available, then it might be necessary to present the user with options in the user interface - e.g., by providing a radio button that would allow the user to choose which Shift to use in the Event Signup. Similar considerations would apply for multiple Locations, Roles, and Statuses.
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.
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:
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.
Also note that clients can enable stricter match rules within specific contexts. These stricter rules do not change how a developer interacts with these endpoints but may reduce the match rate relative to other contexts (e.g., in sandbox accounts). Your VAN Administrator should be able to determine which rules are enabled in their production context. An example of a matching rule is “Disable Partial Matching” which requires a match on full first name and last name in order to match to an existing record (as opposed to using possible nicknames and other permutations of the name).
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,
"subscriptionStatus": "N"
},
{
"email": "jim@fake.ngpvan.com",
"type": "W",
"isPreferred": false,
"isSubscribed": true,
"subscriptionStatus": "S"
},
],
"phones": [
{
"phoneId": 867,
"phoneNumber": "1-555-888-9999",
"phoneType": "H",
"isPreferred": true,
"phoneOptInStatus": "I",
"isCellStatus": {
"statusId": 2,
"statusName": "Likely Cell"
}
},
{
"phoneId": 5309,
"phoneNumber": "1-555-555-1234",
"phoneType": "W",
"ext": 999,
"isPreferred": false,
"isCellStatus": null
}
],
"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"
}
],
"selfReportedRaces": [
{
"reportedRaceId": 4
}
],
"selfReportedEthnicities": [
{
"reportedEthnicityId": 5
}
],
"selfReportedLanguagePreference": {
"reportedLanguagePreferenceId": 6
},
"selfReportedSexualOrientations": [
{
"reportedSexualOrientationId": 1
}
],
"selfReportedGenders": [
{
"reportedGenderId": 1
}
],
"suppressions": [
{
"suppressionCode": "NW",
"suppressionName": "Do not walk"
},
{
"suppressionCode": "NE",
"suppressionName": "Do not email"
}
],
"disclosureFieldValues": [
{
"disclosureFieldId": 1000,
"disclosureFieldValue": "702",
"designationId": 1121
},
{
"disclosureFieldId": 1001,
"disclosureFieldValue": "John",
"designationId": 1121
}
]
}
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 |
contactMethodPreferenceCode |
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 |
selfReportedRaces |
array | n/a | Optional; indicates the person’s race(s). The reportedRaceId must match one of the reported races available in the current context. |
selfReportedEthnicities |
array | n/a | Optional; indicates the person’s ethnicity or ethnicities. 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. |
selfReportedSexualOrientations |
array | n/a | Optional; indicates the person’s sexual orientation(s). The reportedSexualOrientationId must match one of the reported sexual orientations available in the current context. |
selfReportedGenders |
array | n/a | Optional; indicates the person’s gender(s). The reportedGenderId must match one of the reported genders 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. |
disclosureFieldValues |
array | n/a | Optional; An array of Disclosure Field Value objects associated with the person. |
collectedLocationId |
int | n/a | Optional; Location where voter registration application was collected |
electionType |
string | 1 | Optional; type of election registered for. One of G → General, P → Primary, R → Run-off, ‘PP’ → Presidential Primary ‘SP’ → Special Primary, ‘SG’ → Special General, ‘MP’ → Municipal Primary, “MG” → Municipal General, “C” → Caucus, “O” → Other. |
cycle |
string | 4 | Optional; 4 numeric characters indicating election year when registered |
Many of the properties listed above are expressed as arrays (e.g., addresses
, phones
, emails
, etc.). If objects (rather than an array of a single object) are passed, they will be ignored.
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 | Deprecated if Targeted Email is available. Optional; indicates whether the email address may be used in a broadcast email. Default value is true . 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. |
subscriptionStatus |
string | Optional; indicates the email address subscription status for Targeted Email. One of U → unsubscribed, N → neutral, S → subscribed. If unspecified, assumed value is S . Only email addresses with status S will receive messages from Targeted Email. Once an email address has been unsubscribed, it may not be subscribed or set to neutral. This property is only available if Targeted Email is available; it is not valid to set this property and isSubscribed at the same time. |
Property | Type | Description |
---|---|---|
phoneId |
int | Read-only; unique identifier of the phone. |
phoneNumber |
string | Required; after removing all non-numeric characters, the number is evaluated using country specific validation, defaulting to the target context’s country if no other is provided. |
phoneType |
string | Optional; one of: H → home, W → work, C → cell (alias for mobile), M → main, 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 |
isCellStatus |
object | Optional; indicates the level of confidence for whether the phone number is a cell phone. See GET /phones/isCellStatuses for more information. Specifying just a valid value for either the statusId property or the statusName , instead of both, would still work. If no value is provided, any existing explicitly applied isCellStatus for this number will remain unchanged. |
dialingPrefix |
string | Optional; 1 to 3 numeric characters that indicate the country associated with the phone number. If this and countryCode are both specified, they must refer to the same country. |
countryCode |
string | Optional; the ISO alpha-2 code for the country associated with the phone number. If this and dialingPrefix are both specified, they must refer to the same country. |
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. |
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 |
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 |
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” |
Disclosure Fields exist on a range of objects (e.g. People, Contributions) and are used for Disclosure Reports for FEC and state filing purposes.
Property | Type | Description |
---|---|---|
disclosureFieldId |
int | Identifies the Disclosure Field. Together, the designation id and disclosure field id provide a unique identifier of a Disclosure Field. |
disclosureFieldValue |
string | The value of the Disclosure Field |
designationId |
int | The unique identifier of the Designation of the Disclosure Field |
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 |
Attempts to find a person using the given match candidate.
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.
Updates a Person record. Alias for using POST /people/findOrCreate with the vanId
property set to the value of the route parameter.
If no Person with the indicated vanId
is available, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Otherwise responds with a Match Response
Updates a Person record. An alias for using POST /people/findOrCreate with an identifiers
object that has a type
property equal to the personIdType
route parameter and an externalId
property equal to the personId
route parameter.
If no Person with the specified identifier is available, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Otherwise responds with a Match Response
Retrieve a person record and associated contact information
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 , disclosureFieldValues |
GET /people/215501?$expand=phones,emails,addresses,customFields,externalIds,recordedAddresses,preferences,suppressions,reportedDemographics,disclosureFieldValues
Note the following with regards to $expand parameters:
addresses
parameter will provide best known Home
and Mailing
address, if available.recordedAddresses
parameter will provide all available address history, but requires special permissions.preferences
parameter is required to retrieve the following properties: nickname
, website
, and contactMethodPreferenceCode
.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": [
{
"phoneId": 12345,
"phoneNumber": "6175555920",
"ext": "5125",
"dateCreated": "2013-10-25T12:23:00Z",
"phoneType": "Work",
"isPreferred": false,
"phoneOptInStatus": "Opt In",
"isCellStatus": {
"statusId": 3,
"statusName": "Likely Not a Cell"
}
},
{
"phoneId": 23456,
"phoneNumber": "7815550256",
"ext": null,
"dateCreated": "2013-10-25T12:23:00Z",
"phoneType": "Cell",
"isPreferred": true,
"phoneOptInStatus": "Unknown",
"isCellStatus": {
"statusId": 2,
"statusName": "Likely Cell"
}
}
],
"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"
}
],
"disclosureFieldValues": [
{
"disclosureFieldId": 1001,
"disclosureFieldValue": "John",
"designationId": 1121
}
]
}
If the specified vanId
can’t be found, this endpoint will return an error with HTTP Status Code 404 Not Found
.
{
"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), this endpoint will return an error with HTTP Status Code 403 Forbidden
.
{
"errors": [
{
"code": "FORBIDDEN",
"text": "Access to this resource is restricted."
}
]
}
Retrieve a person record and associated contact information. For example /people/DWID:12345
would retrieve a person whose DWID is 12345.
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
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": [
{
"phoneId": 12345,
"phoneNumber": "6175555920",
"ext": "5125",
"dateCreated": "2013-10-25T12:23:00Z",
"phoneType": "Work",
"isPreferred": false,
"phoneOptInStatus": "Opt In",
"isCellStatus": {
"statusId": 3,
"statusName": "Likely Not a Cell"
}
},
{
"phoneId": 23456,
"phoneNumber": "7815550256",
"ext": null,
"dateCreated": "2013-10-25T12:23:00Z",
"phoneType": "Cell",
"isPreferred": true,
"phoneOptInStatus": "Unknown",
"isCellStatus": {
"statusId": 2,
"statusName": "Likely Cell"
}
}
],
"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"
}
],
"disclosureFieldValues": [
{
"disclosureFieldId": 1001,
"disclosureFieldValue": "John",
"designationId": 1121
}
]
}
If the specified vanId
can’t be found, this endpoint will return an error with HTTP Status Code 404 Not Found
.
{
"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), this endpoint will return an error with HTTP Status Code 403 Forbidden
.
{
"errors": [
{
"code": "FORBIDDEN",
"text": "Access to this resource is restricted."
}
]
}
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.
A Canvass Response is expected to be structured like the following:
{
"canvassContext": {
"contactTypeId": 2,
"inputTypeId": 14,
"dateCanvassed": "2012-04-09T00:00:00-04:00",
"phoneId": 867
},
"resultCodeId": null,
"responses": [
{
"activistCodeId": 18917,
"action": "Apply",
"type": "ActivistCode"
},
{
"volunteerActivityId": 3425,
"action": "Apply",
"type": "VolunteerActivity"
},
{
"surveyQuestionId": 109149,
"surveyResponseId": 465468,
"type": "SurveyResponse"
}
]
}
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 . |
Property | Type | Description |
---|---|---|
contactTypeId |
int | Optional; a valid Contact Type ID |
inputTypeId |
int | Optional; a valid Input Type ID (defaults to 11 → API) |
dateCanvassed |
datetime | Optional; the ISO 8601 formatted date that the canvass attempt was made (defaults to today’s date) |
phoneId |
int | Optional; the identifier of the phone number that was called when canvassing this person. May result in a phone suppression in the event of certain kinds of Result Codes (e.g., Wrong Number.) |
Each Script Response has a property that determine’s the response’s type–currently one of ActivistCode, SurveyResponse, and VolunteerActivity.
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 |
Property | Type | Description |
---|---|---|
type |
string | SurveyResponse |
surveyQuestionId |
int | Required; a valid Survey Question ID |
surveyResponseId |
int | Required; a valid Response to the specified surveyQuestionId |
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 |
HTTP Status Code 204 No Content
is returned.
This endpoint is the same as people/{vanId}/canvassResponses but uses external IDs rather than VANIDs.
HTTP Status Code 204 No Content
is returned.
Retrieves a list of Activist Codes on a Person.
This endpoint accepts standard pagination parameters and returns a standard paginated response.
GET /people/123123/activistCodes
{
"items": [
{
"activistCodeId": 3214,
"activistCodeName": "Precinct Captain",
"dateCreated": "2019-05-28T08:45:00Z",
"canvassedBy": null,
"dateCanvassed": "2019-05-28T08:45:00Z"
},
{
"activistCodeId": 36572,
"activistCodeName": "Monthly Newsletter",
"dateCreated": "2019-10-15T11:35:00Z",
"canvassedBy": null,
"dateCanvassed": "2019-10-15T11:35:00Z"
}
],
"nextPageLink": null,
"count": 2
}
Use this endpoint to apply a single Code to a Person.
Property | Type | Description |
---|---|---|
codeId |
int | Required; Unique identifier for an existing Code that is applicable to a Person. |
POST /people/123123/codes
{
"codeId": 123456
}
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
.
In some contexts it is possible to apply both Tags and Source Codes to People. In these contexts, any number of Tags and Source Codes may be accepted. However:
If successful, the endpoint responds with HTTP Status Code 204 No Content
and an empty response body.
This endpoint is the same as people/{vanId}/codes but uses external IDs rather than VANIDs.
See people/{vanId}/codes.
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
.
The same logic for Source Codes and Tags which applies to the POST /people/{vanId}/codes route applies to this route as well.
If successful, the endpoint responds with HTTP Status Code 204 No Content
and an empty response body.
Sets or updates the values of Disclosure Fields.
Property | Type | Description |
---|---|---|
disclosureFieldValues |
array | An array of Disclosure Field Value objects associated with the contribution. |
POST /people/123123/disclosureFieldValues
{
"disclosureFieldValues": [
{
"disclosureFieldId": 1001,
"disclosureFieldValue": "John",
"designationId": -1
},
{
"disclosureFieldId": 1000,
"disclosureFieldValue": "766",
"designationId": 740
},
{
"disclosureFieldId": 139000,
"disclosureFieldValue": "False",
"designationId": 740
}
]
}
HTTP Status Code 204 No Content
is returned.
This endpoint is the same as people/{vanId}/disclosureFieldValues but uses external IDs rather than VANIDs.
HTTP Status Code 204 No Content
is returned.
Use this endpoint to create a single Relationship between two People.
Property | Type | Description |
---|---|---|
relationshipId |
int | Required; Unique identifier for an existing Relationship. |
vanId |
int | Required; Unique identifier of the Person who is related to the Person from the URL route. |
POST /people/123123/relationships
{
"relationshipId": 19,
"vanId": 7890123
}
The Person indicated in the body of the request is the “source” of the relationship, and the Person indicated in the URL route is the “destination” of the relationship. In this case, Person 7890123 is the mother of Person 123123.
If the Person specified in the URL route does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
If the Relationship or Person specified in the request body are not available, this endpoint will return an error or errors with HTTP Status Code 400 Bad Request
.
If successful, the endpoint responds with HTTP Status Code 204 No Content
and an empty response body.
It is possible to use the Public Users system to describe a relationship between a Person and a Public User. Typically this approach is used to create a relationship between a voter in the My Voters and a My Campaign record. To do so:
Step 1. Create a My Campaign record with the relevant public user identifier, as follows:
POST /people/findOrCreate
{
"firstName": "Becky",
"lastName": "Smith",
"identifiers": [
{
"type": "AcmeCRMId",
"externalId": "becky.smith"
}
]
}
Step 2. Use the public user identifier when creating the relationship, leaving the vanId
property null in the request body, as follows:
X-NGPVAN-User-Type: QWNtZUNSTUlk
X-NGPVAN-User-Token: YmVja3kuc21pdGg=
POST /people/1234/relationships
{
"relationshipId": 34
}
Note that the value of the X-NGPVAN-User-Type
header is the result of Base64-encoding “AcmeCRMId”, and the value of the X-NGPVAN-User-Token
header is the result of Base64-encoding “becky.smith”. As a result of this request, a relationship will be created between the voter with VANID 1234, and the MyCampaign record created in Step 1.
Retrieves a list of Notes on a Person.
This endpoint accepts standard pagination parameters and returns a standard paginated response.
By default, this endpoint returns 25 records per request. A maximum of 50 records per request is allowed via the $top
parameter.
GET /people/123123/notes
{
"items": [
{
"noteId": 225,
"text": "Great chat! This person will be able to volunteer next year.",
"isViewRestricted": false,
"category": {
"noteCategoryId": 0,
"name": null
},
"createdDate": "2012-08-22T12:13:00Z"
},
{
"noteId": 484,
"text": "This is my note's text.",
"isViewRestricted": false,
"category": {
"noteCategoryId": 0,
"name": null
},
"createdDate": "2016-02-16T09:00:00Z"
}
],
"count": 55
}
A Note captures data about a Person as free-form text description.
POST /people/123123/notes
{
"text": "Great chat! This person will be able to volunteer next year.",
"isViewRestricted": false,
"category": {
"noteCategoryId": 99
},
"contactHistory": {
"resultCodeId": 5
}
}
Property | Type | Description |
---|---|---|
text |
string | Required; the content of the description of the Person. |
isViewRestricted |
bool | Required; set to true if the note should be restricted only to certain users within the current context; set to false if the note may be viewed by any user in the current context. |
category |
object | Optional; if specified, must be an object whose noteCategoryId corresponds to a Note Category which may be applied to People, and which is available at GET /notes/categories, |
contactHistory |
object | Optional; if specified, creates a Contact History record with the note, and must be a valid Contact History object |
Property | Type | Description |
---|---|---|
contactTypeId |
int | Optional; a valid Contact Type ID |
inputTypeId |
int | Optional; a valid Input Type ID (defaults to 11 → API) |
dateCanvassed |
datetime | Optional; the ISO 8601 formatted date that the canvass attempt was made (defaults to today’s date) |
resultCodeId |
int | Optional; specifies the Result Code of this Contact History. If no resultCodeId is specified, a result of Canvassed is applied. The resultCodeId must be a valid Result Code in the current context. |
HTTP Status Code 204 No Content
is returned.
This endpoint is the same as people/{vanId}/notes but uses external IDs rather than VANIDs.
See people/{vanId}/notes.
HTTP Status Code 204 No Content
is returned.
Updates all properties on an existing Note record. Only text
, isViewRestricted
, and category
may be updated.
PUT /people/123123/notes/456
{
"text": "Great chat! This person will be able to volunteer next year.",
"isViewRestricted": false,
"category": {
"noteCategoryId": 99
}
}
HTTP Status Code 204 No Content
is returned.
Use this endpoint to remove a single Code from a Person.
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.
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.
This endpoint is the same as people/{vanId}/codes but uses external IDs rather than VANIDs.
See people/{vanId}/codes.
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.
Marks this person, who belongs to a master data sharing committee, as an activist who can be viewed in the current context.
Empty request
HTTP Status Code 200 OK
is returned.
Prevents this person, who belongs to a master data sharing committee, from being be viewed in the current context as an activist.
Empty request
HTTP Status Code 200 OK
is returned.
Retrieves a contact’s most recent membership information and other membership information associated with the contact’s membership history.
GET /people/123123/membership
{
"levelId": 123,
"levelName": "Family Level",
"statusName": "Active",
"dateExpireMembership": "2020-11-01T00:00:00Z",
"enrollmentTypeName": "New",
"changeTypeName": "NoChange",
"duesPaid": {
"currencyType": null,
"amount": 10.00
},
"duesEntityTypeName": "Contributions",
"duesAttributionTypeName": "GiftMembership",
"dateCardsSent": "2020-11-26T00:00:00Z",
"numberOfCards": 2,
"dateStartMembership": "2020-11-25T00:00:00Z",
"firstMembershipSourceCode": {
"codeId": 123456,
"codeName": "Acquisition"
},
"numberTimesRenewed": 0,
"numberConsecutiveYears": 0,
"dateLastRenewed": null,
"totalDuesPaid": {
"currencyType": null,
"amount": 10.00
}
}
An Activist Code is 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.
{
"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 . |
Use this endpoint to retrieve all Activist Codes that are available in the current context.
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
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
}
Use this endpoint to retrieve information about a specific Activist Code available in the current context.
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
A standard Activist Code object, if found.
The following is an example of a ballot type.
{
"ballotTypeId": 7,
"name": "Overseas"
}
Property | Type | Description |
---|---|---|
ballotTypeId |
int | Read-only; Unique identifier for a Ballot Type in this context. |
name |
string | Read-only; Name for the Ballot Type |
The following is an example of a ballot return status.
{
"ballotReturnStatusId": 14,
"name": "Not Voted"
}
The following is an overview of the Ballot Return Status object and its related objects
Property | Type | Description |
---|---|---|
ballotReturnStatusId |
int | Read-only; Unique identifier for a Ballot Return Status in this context. |
name |
string | Read-only; Name for the Ballot Return Status |
The following is an example of a ballot request type.
{
"ballotRequestTypeId": 4,
"name": "Mailed"
}
Property | Type | Description |
---|---|---|
ballotRequestTypeId |
int | Read-only; Unique identifier for a Ballot Request Type in this context. |
name |
string | Read-only; Name for the Ballot Request Type |
Retrieve all ballot return statuses available.
This endpoint takes no parameters.
GET /ballotReturnStatuses
This endpoint responds with a standard paged response of all Ballot Return Statuses available in this context.
{
{
"items": [
{
"ballotReturnStatusId": 14,
"name": "Not Voted"
},
{
"ballotReturnStatusId": 19,
"name": "Signature Missing"
}
],
"nextPageLink": null,
"count": 2
}
}
Use this endpoint to retrieve information about a specific Ballot Return Status available in the current context.
Parameter | Location | Type | Description |
---|---|---|---|
ballotReturnStatusId |
route | int | Unique identifier for a specific Ballot Return Status |
GET /ballotReturnStatuses/16
A standard Ballot Return Status object, if found.
If the specified Ballot Return Status does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Retrieve all ballot request types available.
This endpoint takes no parameters.
GET /ballotRequestTypes
This endpoint responds with a standard paged response of all Ballot Request Types available in this context.
{
{
"items": [
{
"ballotRequestTypeId": 4,
"name": "Mailed"
},
{
"ballotRequestTypeId": 5,
"name": "One Stop"
}
],
"nextPageLink": null,
"count": 2
}
}
Use this endpoint to retrieve information about a specific Ballot Request Type available in the current context.
Parameter | Location | Type | Description |
---|---|---|---|
ballotRequestTypeId |
route | int | Unique identifier for a specific Ballot Request Type |
GET /ballotRequestTypes/4
A standard Ballot Request Types object, if found.
If the specified Ballot Request Type does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Retrieve all ballot types available.
This endpoint takes no parameters.
GET /ballotTypes
This endpoint responds with a standard paged response of all Ballot Types available in this context.
{
{
"items": [
{
"ballotTypeId": 6,
"name": "Military"
},
{
"ballotTypeId": 7,
"name": "Overseas"
}
],
"nextPageLink": null,
"count": 2
}
}
Use this endpoint to retrieve information about a specific Ballot Type available in the current context.
Parameter | Location | Type | Description |
---|---|---|---|
ballotTypeId |
route | int | Unique identifier for a specific Ballot Type |
GET /ballotTypes/6
A standard Ballot Types object, if found.
If the specified Ballot Type does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
A Bulk Import Job allows the user to create bulk imports of various resource types such as Contacts or Contributions, and Activist Codes. For a complete list, see the resources endpoint.
API users first create a job with a POST /bulkImportJobs request containing the job parameters, and then make additional requests to GET /bulkImportJobs/{jobId} for the status and content of the job.
Notes:
Currently supported mapping types include the following. Please contact developer support to discuss your use case and request appropriate permissions.
A Bulk Import Job consists of an Upload File and a Mapping Definition. Each Bulk Import Job is of a single Resource Type and may be either creation of new entities, updating existing entities, or a combination of the two.
The Upload File is simple flat tabular data.
Each row of the Upload File contains information about one entity of the given Resource Type. For example, if your Resource Type is Contacts, and you are creating new records, your Upload File might look like this:
GivenName | Surname | StreetAddress | City | State | Zip | HomePhone | HPCountry | MPhone | WorkPhone | ExternalId | |
---|---|---|---|---|---|---|---|---|---|---|---|
Marco | DiNyle | 1630 Revello Drive | Rogerstown | CA | 91115 | marco@Example.com | 413-555-0928 | US | 413-555-0928 | 413-555-0938 | 1234 |
Tamás | Erdélyi | 3976 Poe Road | Springtown | MA | 01909 | tamas@Example.com | 843-555-2852 | US | 843-555-2852 | 843-555-0728 | 2345 |
Mathangi | Arulpragasam | 3314 Villa Drive | Colombo | OH | 91115 | math.ang.i@Example.com | 01632 960387 | GB | 617-555-1224 | 617-555-1000 | 3456 |
Our sample Upload File corresponds to several different Mapping Definitions in a Bulk Import Job.
Some fields can be created initially with the Create Or Update Contact mapping definition if you only want to make a simple Upload File. For example, if you have only one email address or phone number per contact, you can add the email address and phone number as part of the Create Or Update Contact mapping. Other fields always need to be created as part of a separate mapping definition, such as External ID or Origin Source Code. To see what mappings are available to your API key, make a call to GET /bulkImportMappingTypes.
Our sample spreadsheet will correspond to five mapping definitions: one for the base contact definition, one for each of the three different types of phones, and one for the external ID.
{
"name": "CreateOrUpdateContact",
"fieldValueMappings": [
{
"fieldName": "FirstName",
"columnName": "GivenName"
},
{
"fieldName": "LastName",
"columnName": "Surname"
},
{
"fieldName": "AddressLine1",
"columnName": "StreetAddress"
},
{
"fieldName": "City"
},
{
"fieldName": "StateOrProvince",
"columnName": "State"
},
{
"fieldName": "ZipOrPostal",
"columnName": "Zip"
},
{
"fieldName": "Email"
}
]
}
{
"name": "Phones",
"fieldValueMappings": [
{
"fieldName": "Phone",
"columnName": "HomePhone"
},
{
"fieldName": "PhoneTypeID",
"staticValue": "H"
},
{
"fieldName": "PhoneOptInStatusID",
"staticValue": "Opt-In"
},
{
"fieldName": "CountryCode",
"columnName": "HPCountry"
}
]
}
{
"name": "Phones",
"fieldValueMappings": [
{
"fieldName": "Phone",
"columnName": "MPhone"
},
{
"fieldName": "PhoneTypeID",
"staticValue": "C"
},
{
"fieldName": "PhoneOptInStatusID",
"staticValue": "Opt-In"
},
{
"fieldName": "CountryCode",
"staticValue": "US"
}
]
}
{
"name": "Phones",
"fieldValueMappings": [
{
"fieldName": "Phone",
"columnName": "WorkPhone"
},
{
"fieldName": "PhoneTypeID",
"staticValue": "W"
},
{
"fieldName": "PhoneOptInStatusID",
"staticValue": "Unknown"
},
{
"fieldName": "CountryCode",
"staticValue": "US"
}
]
}
{
"name": "ApplyExternalID",
"fieldValueMappings": [
{
"fieldName": "ExternalId"
},
{
"fieldName": "ExternalIdTypeID",
"staticValue": "Friendster"
}
]
}
Bulk Import Jobs are run asynchronously. The entire workflow of initiating a bulk import job and investigating the returned results consists of multiple calls.
jobId
of the bulk import job.GET
return a status
of Complete
, the asynchronous job is completed, and the API user can inspect the results.If at least a subset of the rows in the Upload File are successfully
imported into the database, the status of the GET
call will be
Complete
, and the resultFiles
array will contain links to files
containing information about the Bulk Import Job.
For every row in your upload file that validates, there will be a row in the results file. For the upload file in the Conceptual Overview, the results file should look something like this.
BulkUploadDataID | ULFileID | PrimaryKey | PrimaryKeyType | ExternalID | Phones_1834 | Phones_1835 | ApplyExternalID_1836 |
---|---|---|---|---|---|---|---|
1 | 6135 | 12345 | VanID | 1234 | Processed | Processed | Processed |
2 | 6135 | 31415 | VanID | 2345 | Ignored to avoid overwriting best phone | Processed | Processed |
3 | 6135 | 85753 | VanID | 3456 | Processed | Invalid phone number | Processed |
The columns in the result file can be parsed by the consuming software.
Column | Description |
---|---|
BulkUploadDataID | Data Row ID/Number |
ULFileID | An internal identifier which can be used to track this particular import for troubleshooting. |
PrimaryKey | The unique identifier for the resource. |
PrimaryKeyType | Name of the unique identifier for the resource, e.g. VanID for Contacts, or ContributionID for Contributions. |
requested columnsToIncludeInResultsFile |
Any columns which have been tagged in columnsToIncludeInResultsFile will appear next. In this example, that is the ExternalID column. When creating new records, including a column in the results file can allow you to synchronize between the primary key created with the new record, and the primary key in an external system. This column does not need to have been included in any of the existing field mappings. |
remaining columns: results for each batch | The remainder of the results file contains messages for each of the mapping types in the POST . If a resultFileColumnName has been specified, it will be used; otherwise the column header will be the name of the mapping type followed by an underscore and an identifier. Error messages for individual data imports will appear here. |
The following is an example of a completed Bulk Import Job:
{
"id": 75,
"status": "Completed",
"resourceType": "Contacts",
"resultFileSizeLimitKb": 5000,
"errors": [],
"resultFiles": [
{
"url": "https://somedomain.com/filename.csv",
"dateExpired": "2019-05-15T08:45:50.2062048-04:00"
}
]
}
Property | Type | Description |
---|---|---|
id |
int | Unique identifier for a Bulk Import Job |
status |
string | The status of the Bulk Import Job; may be Pending , InProgress , InProgressWithErrors , Completed , CompletedWithErrors , or Failed |
resourceType |
string | One of the available resourceType options from the GET /bulkImportJobs/resources endpoint. |
resultFileSizeLimitKb |
string | The maximum size in Kb (between 5000 and 100000) of any resulting .csv file. |
errors |
array | A collection of error objects, as described below. |
resultFiles |
array | A collection of file objects in the format [ { url , dateExpired } ]. These are only included if the job status is Completed or CompletedWithError . File access expires after 24 hours. |
An error object can have multiple properties to help debug a failed bulkImportantJob
.
Property | Type | Description |
---|---|---|
referenceCode |
string | A reference for any error which occurred during the processing of the Import Job. We may ask for this code if we are helping you debug errors. Will be null unless status is Error. |
text |
string | A descriptive error string for an error which occurred during the processing of the Import Job. Will be null unless status is Error. |
code |
string | A static string corresponding to the code , which can be used for automated error handling. Will be null unless status is Error. |
This endpoint returns metadata (including job status) about an existing Bulk Import Job, which is specified by the unique identifier jobId
.
GET /bulkImportJobs/12345
Parameter | Location | Type | Description |
---|---|---|---|
jobId |
route | int | unique identifier for a BulkImportJob |
Returns metadata about a BulkImportJob object, if found.
The following is an example of a completed Bulk Import Job:
{
"id": 75,
"status": "Completed",
"resourceType": "Contacts",
"resultFileSizeLimitKb": 5000,
"errors": [],
"resultFiles": [
{
"url": "https://somedomain.com/filename.csv",
"dateExpired": "2019-05-15T08:45:50.2062048-04:00"
}
]
}
Property | Type | Description |
---|---|---|
id |
int | Unique identifier for a Bulk Import Job |
status |
string | The status of the Bulk Import Job; may be Pending , InProgress , InProgressWithErrors , Completed , CompletedWithErrors , or Failed |
resourceType |
string | One of the available resourceType options from the GET /bulkImportJobs/resources endpoint. |
resultFileSizeLimitKb |
string | The maximum size in Kb (between 5000 and 100000) of any resulting .csv file. |
errors |
array | A collection of error objects, as described below. |
resultFiles |
array | A collection of file objects in the format [ { url , dateExpired } ]. These are only included if the job status is Completed or CompletedWithError . File access expires after 24 hours. |
An error object can have multiple properties to help debug a failed bulkImportantJob
.
Property | Type | Description |
---|---|---|
referenceCode |
string | A reference for any error which occurred during the processing of the Import Job. We may ask for this code if we are helping you debug errors. Will be null unless status is Error. |
text |
string | A descriptive error string for an error which occurred during the processing of the Import Job. Will be null unless status is Error. |
code |
string | A static string corresponding to the code , which can be used for automated error handling. Will be null unless status is Error. |
If the specified jobId
is inaccessible or does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
This endpoint returns an array of strings that correspond to the resourcesTypes
available to the API user.
GET /bulkImportJobs/resources
[
"Contacts",
"Contributions",
...
]
Property | Type | Description |
---|---|---|
resourceType |
string | A unique resource type used in a Bulk Import Job. |
This endpoint returns all the available ways you can map your file columns and values to accepted models that can be imported during a bulk import operation.
This information lets you know what can be imported during your operation, what are the characteristics of those fields and their columns, which columns have a predefined list of possible data, etc.
With this information, you can build your POST to the bulkImportJobs endpoint to map some information directly from your uploaded file, hardcode some information as static, map your uploaded data to other values, or make whatever mappings are necessary to create your import.
GET /bulkImportMappingTypes
{
"items": [
{
"name": "MailingAddress",
"displayName": "Apply Mailing Address",
"uploadType": null,
"allowMultipleMode": "Single",
"resourceTypes": ["Contacts"],
"fields": [
{
"name": "MailingAddress",
"description": "Address Line 1",
"hasPredefinedValues": false,
"isRequired": false,
"canBeMappedToColumn": true,
"parents": null
},
{
"name": "MailingStateOrProvince",
"description": "State/Province. Predefined Values are only for United States Addresses.",
"hasPredefinedValues": true,
"isRequired": false,
"canBeMappedToColumn": true,
"parents": [
{
"parentFieldName": "MailingCountryCode",
"limitedToParentValues": null
}
]
}
]
},
{
"name": "ApplyContactCustomFields",
"displayName": "Apply Custom Contact Fields",
"uploadType": null,
"allowMultipleMode": "Multiple",
"resourceTypes": ["Contacts"],
"fields": [
{
"name": "MyCustomField1",
"description": "My Custom Field Checkbox 1 - requires Custom Contact Field Group to be mapped to My Custom Contact Fields",
"hasPredefinedValues": true,
"isRequired": false,
"canBeMappedToColumn": true,
"parents": [
{
"parentFieldName": "CustomFieldGroupID",
"limitedToParentValues": [
{
"name": "My Custom Contact Fields",
"id": "100"
}
]
}
]
}
]
},
],
"nextPageLink": null,
"count": 2
}
]
Property | Type | Description |
---|---|---|
name |
string | The unique name of the mapping type |
displayName |
string | A human readable version of the field name |
allowMultipleMode |
string | If Single , you can only apply one of this mapping in a single job; if SinglePerType , the entity can only have one value per type at a time (e.g. one Home Phone, and one Cell Phone) so you can specify multiple of this mapping as long as they are of different types; if Multiple , the entity may have many values set for this Field and you can apply as many of this mapping in one request as desired |
resourceTypes |
array | The names of the resourceType to which this field can be applied, such as Contacts or Contributions |
fields |
array | An array describing the possible field/column mappings available for this mapping type. |
The fields
array, describing the column mappings available in this field item, can have the below properties:
Property | Type | Description |
---|---|---|
name |
string | The name of the field/column |
description |
string | A human readable description of the column |
hasPredefinedValues |
boolean | Whether the column requires a predefined set of possible values, under at least some circumstances |
isRequired |
boolean | If true , the value for this field must be provided in bulk import, either from a mapped column or static value |
canBeMappedToColumn |
boolean | Whether the column can draw values from your uploaded file, rather than requiring values be set statically for the entire upload file |
parents |
array | An array of other fields which must be mapped if this field has prerequisite dependencies |
The parents
array lists one or more prerequisites for this field to be mapped.
Property | Type | Description |
---|---|---|
parentFieldName |
string | The name of a field which must be mapped in order for the child mapping to be created |
limitedToParentValues |
array | Optional; A collection of permitted values for the parent field that is a prerequisite for the child mapping. Will be null if there is no constraint on the parent value. |
The limitedToParentValues
array is a collection of the limited set of permitted values which are required for the parent field.
Property | Type | Description |
---|---|---|
name |
string | The name of the permitted value |
id |
string | The unique identifier of the permitted value |
This endpoint returns all the available ways you can map your file columns and values to accepted models that can be imported during a bulk import operation.
This information lets you know what can be imported during your operation, what are the characteristics of those fields and their columns, which columns have a predefined list of possible data, etc.
With this information, you can build your POST to the bulkImportJobs endpoint to map some information directly from your uploaded file, hardcode some information as static, map your uploaded data to other values, or make whatever mappings are necessary to create your import.
GET /bulkImportMappingTypes/mailingAddress
Parameter | Location | Type | Description |
---|---|---|---|
mappingTypeName |
route | string | Must correspond to an items.name value returned from GET /bulkImportMappingTypes |
{
"name": "MailingAddress",
"displayName": "Apply Mailing Address",
"uploadType": null,
"allowMultipleMode": "Single",
"resourceTypes": ["Contacts"],
"fields": [
{
"name": "MailingAddress",
"description": "Address Line 1",
"hasPredefinedValues": false,
"isRequired": false,
"canBeMappedToColumn": true,
"parents": null
},
{
"name": "MailingStateOrProvince",
"description": "State/Province. Predefined Values are only for United States Addresses.",
"hasPredefinedValues": true,
"isRequired": false,
"canBeMappedToColumn": true,
"parents": [
{
"parentFieldName": "MailingCountryCode",
"limitedToParentValues": null
}
]
}
]
}
Property | Type | Description |
---|---|---|
name |
string | The unique name of the mapping type |
displayName |
string | A human readable version of the field name |
allowMultipleMode |
string | If Single , you can only apply one of this mapping in a single job; if SinglePerType , the entity can only have one value per type at a time (e.g. one Home Phone, and one Cell Phone) so you can specify multiple of this mapping as long as they are of different types; if Multiple , the entity may have many values set for this Field and you can apply as many of this mapping in one request as desired |
resourceTypes |
array | The names of the resourceType to which this field can be applied, such as Contacts or Contributions |
fields |
array | An array describing the possible field/column mappings available for this mapping type. |
The fields
array, describing the column mappings available in this field item, can have the below properties:
Property | Type | Description |
---|---|---|
name |
string | The name of the field/column |
description |
string | A human readable description of the column |
hasPredefinedValues |
boolean | Whether the column requires a predefined set of possible values, under at least some circumstances |
isRequired |
boolean | If true , the value for this field must be provided in bulk import, either from a mapped column or static value |
canBeMappedToColumn |
boolean | Whether the column can draw values from your uploaded file, rather than requiring values be set statically for the entire upload file |
parents |
array | An array of other fields which must be mapped if this field has prerequisite dependencies |
The parents
array lists one or more prerequisites for this field to be mapped.
Property | Type | Description |
---|---|---|
parentFieldName |
string | The name of a field which must be mapped in order for the child mapping to be created |
limitedToParentValues |
array | Optional; A collection of permitted values for the parent field that is a prerequisite for the child mapping. Will be null if there is no constraint on the parent value. |
The limitedToParentValues
array is a collection of the limited set of permitted values which are required for the parent field.
Property | Type | Description |
---|---|---|
name |
string | The name of the permitted value |
id |
string | The unique identifier of the permitted value |
Some fields have a predefined list of possible values which can be applied during a bulk import, corresponding, for example, to a drop-down list or a checkbox. This endpoint returns an ID and name property for each value that is allowed as an input. When preparing input data, input values should take the form of the ID of the value rather than the name to avoid potential collisions. However, if available value names are unique, names will be accepted as input values.
/bulkImportMappingTypes/{mappingTypeName}/{fieldName}/values
{
"items": [
{
"name": "Other",
"id": "3",
"parents": null
},
{
"name": "Personal",
"id": "1",
"parents": null
},
{
"name": "Work",
"id": "2",
"parents": [
{
"parentFieldName": "WorkFieldParent",
"allowedParentValues": [
{
"name": "Work Field 1",
"id": "WF1"
}
]
}
]
}
"nextPageLink": null,
"count": 3
}
Property | Type | Description |
---|---|---|
name |
string | The human-friendly label for the predefined value |
id |
string | The unique identifier for the predefined value |
parents |
array | An array of other fields’ values which must be mapped before this value can be used for this field |
The parents
array lists one or more prerequisites for this field to be mapped.
Property | Type | Description |
---|---|---|
parentFieldName |
string | The name of a field which must be mapped in order for the child mapping to be created |
allowedParentValues |
array | The collection of legal values for the parent field which are prerequisite for the child mapping to be created |
The allowedParentValues
array is a collection of the limited set of legal values which are required for the parent field.
Property | Type | Description |
---|---|---|
name |
string | The name of the permitted value |
id |
string | The unique identifier of the permitted value |
Initiates a bulk import job by specifying the url for a zipped, delimited
file, of no more than 100MB. A bulk import job can update and/or create
multiple data types including, but not limited to, Contacts
,
Contributions
, and ActivistCodes
. For a complete list of supported types, see the
resources endpoint.
The zipped file can contain both update and creation records for a single
resource type. It can also contain a header row. The header row is only
there as a debugging aid, and is not used by the import process. See
Property hasHeader
in the File object for more
information on headers.
When the bulk import job is updating resources, if any non-required columns are left blank, those fields will not be updated. This process cannot be used to delete information; it can only update or create.
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. The file can be up to 100 MB (100,000 KB) in size. |
actions |
array | Required; An array of Action objects, each defining an action to be taken. |
Property | Type | Description |
---|---|---|
fileName |
string | Required; Name of the delimited file within the zip file accessible by sourceUrl (e.g., MyImportData.csv ). |
hasHeader |
bool | Optional; Indicates that the first line of the file should be skipped. A header row in the file will be not be used; column names are determined by the required columns array and the order that the columns appear in the file. Defaults to false . |
hasQuotes |
bool | Optional; Indicates that fields are enclosed in quotation marks within each column of the file. Defaults to false . Important: If any instances of the delimiter character appear in your file itself, you will need to make sure to quote those strings and set this to true . This is very likely if you use commas as your delimiter, as commas appear in many fields you are likely to upload (eg. a Long Name of Names, with, commas in a .csv file). If you create your data with a spreadsheet program, it will probably quote the strings with delimiter in them automatically when saving. |
sourceUrl |
string | Required; URL at which a zip file containing fileName can be accessed. The following URL schemes (“protocols”) are supported: SFTP, FTPS, HTTPS. If authentication is required, the username and password should be included in the URL (e.g., sftp://user:password@foo.bar.us/my_import_data.zip). |
columnDelimiter |
string | Optional; Character that separates each each column; one of: Csv → comma (,) separated values, Tab → Tab separated values, Pipe → pipe (|) separated values. Defaults to CSV . |
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. |
A column name
must be present for every column in the uploaded file, listed in the order in which they appear in the file from left to right. See mapping types for more information.
Property | Type | Description |
---|---|---|
name |
string | Required; A column’s unique, alphanumeric name that can be referenced in actions (e.g., VanID). |
The first column of a file is restricted based on the ResourceType and MappingType and must match or be mapped to a specific column name; however the match is case insensitive.
ResourceType | MappingType | Required Column Name |
---|---|---|
Contacts |
All Except For CreateOrUpdateContact | VanId |
Contributions |
ContributionAdjustments | ContributionId |
Contributions |
EditContributionData | ContactsContributionId |
ContributionAdjustments |
ContributionAdjustments | ContributionId |
ContributionAdjustments |
EditContributionData | ContactsContributionId |
Required properties: actionType
, ResourceType
, and ResultFileSizeKbLimit
.
Property | Type | Description |
---|---|---|
actionType |
string | Required; The string loadMappedFile . |
resourceType |
string | Required; The type of resource being updated. Available options: Contacts , Contributions , ActivistCodes , or ContactsActivistCodes . |
resultFileSizeKbLimit |
integer | Required; The maximum size in kilobytes of any result file returned. |
mappingTypes |
array | Required; Collection of mappings to apply to the file, translating uploaded tabular data to our object models. |
columnsToIncludeInResultsFile |
array | An array of Column objects to be included in the bulk import job’s results file (for example, to synchronize with an external ID to an external data source). |
The mappingTypes
array encodes a series of field mapping definitions. These define the supported methods
for mapping out the flat data in your file, in order to translate it into datatypes understood by our import system.
The available mapping types can be discovered from the GET /bulkImportMappingTypes endpoint.
Property | Type | Description |
---|---|---|
name |
string | Required; The name of the field mapping type |
fieldValueMappings |
array | Optional; Any mappings, static values, or other options for this field mapping. This array is not needed if your input is using built-in mappings. For example, if your Columns array uses the names of our fields, your values are already in a format that will be accepted by our system, and no other options are required, it is not necessary to set these values. |
resultFileColumnName |
string | Optional; A string to represent this mapping in the results file produced by bulk import, if the default string is not desired |
The fieldValueMappings
array contains definitions for the columns mapped as part of this field mapping.
If a column or a property is left out of the array, default values will be used, wherever possible.
Property | Type | Description |
---|---|---|
fieldName |
string | The name of this field’s column, as discovered by GET /bulkImportMappingTypes. |
columnName |
string | If this column, as defined in the Columns array, does not have the same name as the fieldName , include the column name here. |
staticValue |
string | If this field should be using a static value for the entire bulk import, instead of drawing a value from the uploaded file, set that value here. |
values |
array | A collection of translations from values in the uploaded file to values as they should be imported into our system. |
The values
array is for those occasions where the uploaded file include data in some external format,
and it needs to be translated into data as it is understood by our object models. For example, an external
system creating the bulk import uploaded file encode types as “ccard”, “$$”, and “vmo”, which would be
translated via the values
array into “Credit Card”, “Cash”, and “Venmo”.
Property | Type | Description |
---|---|---|
sourceValue |
string | What string should be translated when it is found in this column in the uploaded file. |
targetValue |
string | A string representation of the value to which the sourceValue should be translated. |
POST /bulkImportJobs
{
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{ "name": "GivenName" },
{ "name": "MiddleInitial" },
{ "name": "Surname" },
{ "name": "StreetAddress" },
{ "name": "City" },
{ "name": "State" },
{ "name": "ZipCode" },
{ "name": "EmailAddress" },
{ "name": "TelephoneNumber" },
{ "name": "Birthday" },
{ "name": "mStreet" },
{ "name": "mApt" },
{ "name": "mCity" },
{ "name": "mState" },
{ "name": "mZIP" },
{ "name": "mCountry" },
{ "name": "CodeId" }
],
"columnDelimiter": "Csv"
},
"description": "A bulk import of new users with basic contact information",
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "OriginSourceCode",
"fieldValueMappings": [
{ "fieldName": "CodeId" }
]
},
{
"name": "CreateOrUpdateContact",
"resultFileColumnName": "NewPerson",
"fieldValueMappings": [
{
"fieldName": "FirstName",
"columnName": "GivenName"
},
{
"fieldName": "MiddleName",
"columnName": "MiddleInitial"
},
{
"fieldName": "LastName",
"columnName": "Surname"
},
{
"fieldName": "AddressLine1",
"columnName": "StreetAddress"
},
{
"fieldName": "City",
"columnName": "City"
},
{
"fieldName": "StateOrProvince",
"columnName": "State"
},
{
"fieldName": "ZipOrPostal",
"columnName": "ZipCode"
},
{
"fieldName": "Email",
"columnName": "EmailAddress"
},
{
"fieldName": "Phone",
"columnName": "TelephoneNumber"
},
{
"fieldName": "DOB",
"columnName": "Birthday"
}
]
},
{
"name": "MailingAddress",
"fieldValueMappings": [
{
"fieldName": "MailingAddress",
"columnName": "mStreet"
},
{
"fieldName": "MailingAddressLine2",
"columnName": "mApt"
},
{
"fieldName": "MailingCity",
"columnName": "mCity"
},
{
"fieldName": "MailingStateOrProvince",
"columnName": "mState"
},
{
"fieldName": "MailingZipOrPostal",
"columnName": "mZIP"
},
{
"fieldName": "MailingCountryCode",
"columnName": "mCountry",
"values": [
{
"sourceValue": "America",
"targetValue": "US"
}
]
},
{
"fieldName": "MailingDisplayAsEntered",
"staticValue": "1"
}
]}
]}
]}
In this example, a bulk upload of Contacts will be created that applies multiple ExternalID
fields to each uploaded Contact. One External ID, the one in the third column in the
uploaded file, is of varying type, and draws its ExternalIDType
from the second
column in the uploaded file. This is the external ID which will be included in the results file.
The fourth column in the uploaded file contains another external ID. These are
all hardcoded to the ExternalIDType
of “1”.
POST /bulkImportJobs
{
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{"name": "vanid" },
{"name": "ExternalIdTypeID"},
{"name": "ExternalId"},
{"name": "ID2"}
],
"columnDelimiter": "Csv"
},
"description": "A bulk import of external IDs",
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"columnsToIncludeInResultsFile": [
{"name": "ExternalIdTypeID"}
],
"mappingTypes": [
{
"name": "ApplyExternalID",
"fieldValueMappings": [
{ "fieldName": "ExternalIdTypeID" },
{ "fieldName": "ExternalId" }
]
},
{
"name": "ApplyExternalID",
"fieldValueMappings": [
{
"fieldName": "ExternalIdTypeID",
"staticValue": "1"
},
{
"fieldName": "ExternalId",
"columnName": "ID2"
}
]
}
]}
]}
In this example, a bulk upload of Contacts will be created that applies multiple custom contact fields to each uploaded Contact. Multiple custom fields belonging to the same custom field group may be mapped, but you cannot mix custom fields from different custom field groups. Multiple custom contact groups may be added as separate mappingTypes.
POST /bulkImportJobs
{
"description": "A bulk import with custom contact fields",
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{
"name": "VANID"
},
{
"name": "CustomNumber_389"
},
{
"name": "CF390"
}
],
"columnDelimiter": "Csv"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "ApplyContactCustomFields",
"fieldValueMappings": [
{
"fieldName": "CustomFieldGroupID",
"staticValue": "1109"
},
{
"fieldName": "CF389",
"columnName": "CustomNumber_389"
},
{
"fieldName": "CF390"
}
]
}
]
}
]}
In this example, a bulk upload of Contacts will be created or updated with the mapped levels of organizing turf.
You can only map one organizing turf per Contact and all turf levels must be supplied; any existing values will be overwritten.
Supplying values outside the current turf hierarchy will result in a Failed
job status.
POST /bulkImportJobs
{
"description": "A bulk import with organizing turfs",
"file": {
"fileName": "my_bulk_upload.csv",
"hasHeader": true,
"hasQuotes": false,
"sourceUrl": "https://a-place-for-files.com/my_bulk_upload.zip",
"columns": [
{
"name": "VANID"
},
{
"name": "Region"
},
{
"name": "Organizer"
},
{
"name": "Team"
}
],
"columnDelimiter": "Comma"
},
"actions": [
{
"resultFileSizeKbLimit": 5000,
"resourceType": "Contacts",
"actionType": "loadMappedFile",
"mappingTypes": [
{
"name": "ApplyOrganzingTurfs",
"fieldValueMappings": [
{
"fieldName": "CF123",
"columnName": "Region"
},
{
"fieldName": "CF124",
"columnName": "Organizer"
},
{
"fieldName": "CF125",
"columnName": "Team"
}
]
}
]
}
]}
A successful POST returns the jobId
of the bulk import job.
{
"jobId": 998877
}
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.
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.
Parameter | Location | Type | Description |
---|---|---|---|
inputTypeId |
query | int | Optional; filter Contact Types to those available to the given Input Type |
GET /canvassResponses/contactTypes?inputTypeId=11
[
{
"contactTypeId": 1,
"name": "Phone"
},
{
"contactTypeId": 2,
"name": "Walk"
}
]
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.
GET /canvassResponses/inputTypes
[
{
"inputTypeId": 11,
"name": "API"
},
{
"inputTypeId": 4,
"name": "Bulk"
},
{
"inputTypeId": 2,
"name": "Manual"
},
{
"inputTypeId": 14,
"name": "Mobile"
},
{
"inputTypeId": 10,
"name": "VPB"
},
{
"inputTypeId": 23,
"name": "Website"
}
]
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.
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.”
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
[
{
"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"
}
]
A Changed Entity Export Job is a process that provides bulk data to API consumers about entities that have changed in the last 90 days. Each successful job results in the creation of one or several .csv
files that may be downloaded before their expiration dates.
Developers might first catalog the available Resource Types as well as the available Fields and ChangeTypes for each type.
Once a framework is established, API users first create a job with a POST /changedEntityExportJobs request containing the job parameters, and then make additional requests to GET /changedEntityExportJobs/{exportJobId} for the status and content of the job.
Currently supported entities include the following. Please contact developer support to discuss your use case and request appropriate permissions.
The following is an example of a completed Changed Entity Export Job:
{
"exportJobId": 12345,
"jobStatus": "Complete",
"dateChangedFrom": "2019-01-01T01:02:03+04:00",
"dateChangedTo": "2019-01-01T07:03:09+04:00",
"files": [
{
"downloadUrl": "https://www.example.com/some-unique-file-name.csv",
"dateExpired": "2019-01-31T15:05:54.2106809-04:00"
}
],
"message": "Finished processing export job",
"code": null,
"exportedRecordCount": 10500,
"excludeChangesFromSelf": "true"
}
Property | Type | Description |
---|---|---|
exportJobId |
int | Unique identifier for a Changed Entity Export Job |
jobStatus |
string | Pending , InProcess , Error , Complete |
dateChangedFrom |
date | User-specified timestamp in the format YYYY-MM-DDThh:mm:ss.00Z or YYYY-MM-DDThh:mm:ss.00 -hh:mm . Must be in the last 90 days. |
dateChangedTo |
date | User-specified timestamp in same format as dateChangedFrom . Server-generated if not provided. |
files |
array | Collection of file objects in the format [ { downloadUrl , dateExpired } ] |
message |
string | Additional information about the job status |
code |
string | null if there is no error, otherwise a reference code for debugging |
exportedRecordCount |
int | The number of records contained across all export files |
excludeChangesFromSelf |
bool | If true , records updated in EveryAction by requesting API user will not be exported. This option could be used to prevent “circular updates” in bidirectional integrations where the same API key is used for both pulling changes and applying changes |
This endpoint returns an array of strings that correspond to the resourcesTypes
available to the API user.
GET /changedEntityExportJobs/resources
[
"Contacts",
"Contributions",
"OtherAvailableResourceTypes",
...
]
Property | Type | Description |
---|---|---|
resourceType |
string | A unique resource type used in a Changed Entity Export Job. |
Some resourceTypes will return a ChangeTypeID and associated data in their export files to indicate the type of the last change made to an exported record. This endpoint retrieves a collection of available changeTypes for a specified resourceType with metadata about each changeType.
GET /changedEntityExportJobs/changeTypes/{resourceType}
Parameter | Type | Description |
---|---|---|
resourceType |
route | One of the available resourceType options from the /resources endpoint. |
[
{
“ChangeTypeID”: “1”,
“ChangeTypeName”: “CreatedOrUpdated”,
“Description”: “Indicates that the last change to the record was a create or update”,
},
{
“ChangeTypeID”: “2”,
“ChangeTypeName”: “Merged”,
“Description”: “Indicates that the last change to the record was a merge”,
}
]
Property | Type | Description |
---|---|---|
ChangeTypeID |
int | The ID of the ChangeType |
ChangeTypeName |
string | The name of the ChangeType |
Description |
string | The description of the ChangeType |
Retrieve a collection of available fields for a specified resourceType
with metadata about each field.
GET /changedEntityExportJobs/fields/{resourceType}
Property | Type | Description |
---|---|---|
resourceType |
route | One of the available resourceType options from the /resources endpoint. |
Returns a collection of field
entities for a specified resourceType
.
[
{
"fieldName": "Address",
"fieldType": "T",
"maxTextboxCharacters": 200,
"isCoreField": true,
"availableValues": null
},
{
"fieldName": "WorkEmail",
"fieldType": "T",
"maxTextboxCharacters": 100,
"isCoreField": false,
"availableValues": null,
"bulkImportFields": [
{
"mappingTypeName": "CreateOrUpdateContact",
"fieldName": "WorkEmail"
},
{
"mappingTypeName": "Email",
"fieldName": "Email",
"relationalMappings": [
{
"fieldName": "EmailTypeId",
"value": "Work"
}
]
}
]
},
{
"fieldName": "WorkEmailSubscriptionStatus",
"fieldType": "N",
"maxTextboxCharacters": null,
"isCoreField": false,
"availableValues": [
{
"id": 0,
"name": "Unsubscribed"
},
{
"id": 1,
"name": "Not Subscribed"
},
{
"id": 2,
"name": "Subscribed"
}
]
}
]
Parameter | Type | Description |
---|---|---|
fieldName |
string | name of the field; corresponds to the requestedFields value in a POST request |
fieldType |
string | type of the field; corresponds to the available fieldTypes below |
maxTextboxCharacters |
int | maximum length of a string field |
isCoreField |
bool | true if a field will always be exported, or false if it must be specified in the requestedFields property |
availableValues |
array | collection of id /name values; available only if a field has an enumerated list of static values |
bulkImportFields |
array | collection of objects describing the bulk import mapping type and fields necessary for importing the analagous export data |
Available fieldTypes
:
Explanation of bulkImportFields
:
The Changed Entity Export and the Bulk Import API provide a way to export and import data from and to our system respectively. However, there is not always a one to one relationship between
an imported field and an exported field; bulkImportFields
attempts to provide information on how those two relate to each other.
MappingTypeName: Name of the bulk import mapping type.
FieldName: The bulk import field that is exportable as the CEE field.
RelationalMapping: Some exported fields can only be imported based on the settings of a different mapping type in the bulkImportJob
. relationalMapping
gives information about the prerequisite mappings. For example, the exported field WorkEmail
would be imported using the Email
mapping type, with the prerequisite of setting the EmailTypeId
field to work
.
Use this endpoint to request a new Changed Entity Export Job for a specified resourceType
with properties provided in the request body. The generated dataset will be one or multiple files that include all records which have changed between dateChangedFrom
(specified by the user) and dateChangedTo
(generated by the server at execution). Optionally, the user may also specify that inactive records be included in the export file with the includeInactive
property. ChangeTypes began being stored in September 2020. Records for which the last change occurred before this date may be missing inaccurate ChangeTypes until they are updated. The user may also specify additional IDs with the requestedIds
property to add to the dataset. The exported data will include all core fields for the resource type as well as any specified by the user with the requestedFields
or requestedCustomFieldIds
properties. If all generated content is less than the fileSizeKbLimit
, then one file will be created. Otherwise, multiple files will be created such that none exceeds the specified limit.
If the dateChangedTo
parameter is in the past, the resulting records will be any which changed in the dateChangedFrom
and dateChangedTo
window. However, the records that will be returned by the job will always be the current version of the records. They will not be records at the snapshot moment in time of dateChangedTo.
{
"dateChangedFrom": "2019-01-01T01:02:03+04:00",
"resourceType": "Contacts",
"requestedIds": [1, 23, 456, 7890],
"requestedFields": ["Prefix", "LastUpdatedOn", "DateCreated"],
"fileSizeKbLimit": 15000
}
Property | Type | Description |
---|---|---|
dateChangedFrom |
date | Required; timestamp in the format YYYY-MM-DDThh:mm:ss.00Z or YYYY-MM-DDThh:mm:ss.00 -hh:mm . Must be in the last 90 days. |
dateChangedTo |
date | Optional; timestamp in the format YYYY-MM-DDThh:mm:ss.00Z or YYYY-MM-DDThh:mm:ss.00 -hh:mm . If provided, must be a date that is more recent than dateChangedFrom, and must be no later than the present. If not provided, will be set automatically to the time at which the API request is made. |
resourceType |
string | Required; available resource type specified at the /resources endpoint |
requestedIds |
array | IDs to be included in the exported set if available. Overrides the time window specified as well as the includeInactive property. |
requestedFields |
array | Names of non-core fields to be included in the export |
requestedCustomFieldIds |
array | IDs of custom fields to be included in the export |
fileSizeKbLimit |
int | The maximum size in Kb (between 5000 and 100000) of any exported .csv file; defaults to 40000 |
includeInactive |
bool | If set to “true”, includes inactive records such as archived activist codes or deleted contacts. Defaults to “false”. |
If successful, the endpoint responds with HTTP Status Code 201 Created
and the integer ID of the created export job in the response body. It will also return all the requested properties. Any missing properties in the response indicates that they were not accepted and will not be processed.
Note that dateChangedFrom
value from the user may be expressed as Z
Zulu Time (UTC -00:00
) or a time offset, such as +02:00
.
The following is an example of a completed Changed Entity Export Job:
{
"exportJobId": 12345,
"jobStatus": "Complete",
"dateChangedFrom": "2019-01-01T01:02:03+04:00",
"dateChangedTo": "2019-01-01T07:03:09+04:00",
"files": [
{
"downloadUrl": "https://www.example.com/some-unique-file-name.csv",
"dateExpired": "2019-01-31T15:05:54.2106809-04:00"
}
],
"message": "Finished processing export job",
"code": null,
"exportedRecordCount": 10500,
"excludeChangesFromSelf": "true"
}
Property | Type | Description |
---|---|---|
exportJobId |
int | Unique identifier for a Changed Entity Export Job |
jobStatus |
string | Pending , InProcess , Error , Complete |
dateChangedFrom |
date | User-specified timestamp in the format YYYY-MM-DDThh:mm:ss.00Z or YYYY-MM-DDThh:mm:ss.00 -hh:mm . Must be in the last 90 days. |
dateChangedTo |
date | User-specified timestamp in same format as dateChangedFrom . Server-generated if not provided. |
files |
array | Collection of file objects in the format [ { downloadUrl , dateExpired } ] |
message |
string | Additional information about the job status |
code |
string | null if there is no error, otherwise a reference code for debugging |
exportedRecordCount |
int | The number of records contained across all export files |
excludeChangesFromSelf |
bool | If true , records updated in EveryAction by requesting API user will not be exported. This option could be used to prevent “circular updates” in bidirectional integrations where the same API key is used for both pulling changes and applying changes |
This endpoint returns status and metadata about an existing Changed Entity Export Job, which is specified by the unique identifier exportJobId
.
GET /changedEntityExportJobs/12345
Parameter | Location | Type | Description |
---|---|---|---|
exportJobId |
route | int | Unique identifier for a ChangedEntityExportJob |
Returns metadata about a ChangedEntityExportJob object, if found.
{
"exportJobId": 12345,
"jobStatus": "Complete",
"dateChangedFrom": "2019-01-01T01:02:03+04:00",
"dateChangedTo": "2019-01-01T07:03:09+04:00",
"files": [
{
"downloadUrl": "https://www.example.com/some-unique-file-name.csv",
"dateExpired": "2019-01-31T15:05:54.2106809-04:00"
}
],
"message": "Finished processing export job",
"code": null,
"exportedRecordCount": 10500
}
Property | Type | Description |
---|---|---|
exportJobId |
int | Unique identifier for a Changed Entity Export Job |
jobStatus |
string | Pending , InProcess , Error , Complete |
dateChangedFrom |
date | User-specified timestamp in the format YYYY-MM-DDThh:mm:ss.00Z or YYYY-MM-DDThh:mm:ss.00 -hh:mm |
dateChangedTo |
date | Server-generated timestamp in the format YYYY-MM-DDThh:mm:ss.00 -hh:mm |
files |
array | Collection of file objects in the format [ { downloadUrl , dateExpired } ]. File access expires after 24 hours. |
message |
string | Additional information about the job status |
code |
string | null if there is no error, otherwise a reference code for debugging |
exportedRecordCount |
int | The number of records contained across all export files |
If the specified exportJobId
is inaccessible or does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
{
"errors": [
{
"code": "NOT_FOUND",
"text": "The specified resource cannot be found."
}
]
}
Codes are a hierarchical categorization system which may be applied to a variety of Entities.
There ar two types of Codes: Source Codes, and Tags. Source Codes are used to indicate the effort or activity which caused an Entity to be added to the database; at most one Source Code may be applied to any given Entity. Tags may be used to indicate a variety of properties about an Entity; any number of Tags may be applied to a given Entity.
Source Codes may only be applied to the following Entities only: People, Events, and Contributions. Tags may be applied to People, Events, and other Entities. The list of Entities to which a Tag may be applied depends on the context of the API key in use; the GET /entities/supportedEntities route may be used to determine which Entities may have Tags applied for an given API key.
The hierarchical nature of Codes makes it possible for a single Code to convey several pieces of information at once. For example, you could categorize a variety of marketing campaigns in a hierarchical manner:
If the Promoted tweets Code is applied to a Contribution, that conveys three pieces of information: that the Contribution came from Digital Ads, and more specifically from Twitter, and finally that it came from Promoted tweets. This hierarchy allows a single Code to carry a significant amount of information because each Code can have a parent (e.g., the parent of Promoted tweets is Twitter.) As is demonstrated in the above example, Codes need not have the same number of parents, grand-parents, etc. Promoted tweets is three levels deep whereas Post cards is only two levels deep.
Codes have another helpful attribute called applicability. In some cases, a Code’s parent may be able to stand on its own. For example, if Post cards is too specific of an attribute for certain kinds of Contributions, Bulk mail may suffice. In this case, it’d make sense to allow Bulk mail to be Applicable.
In the case of Digital Ads, you may decide that your classifications are complete enough that you do not want to simply classify something as Twitter. In that case, you’d make Twitter be Searchable Only. This means that you can find Contributions marked with any Twitter promotion, but no Contribution can be just from Twitter only.
Use the Codes endpoint to create, update, and delete Tags and Source Codes, as well as to discover existing Tags and Source Codes, and to retrieve metadata about each. You can perform these operations on a single code or on a batch of codes.
Codes are applied using the appropriate endpoint for the supported entity to which the Code is being applied. For example, to apply Codes to a Person, use POST /people/{vanId}/codes.
The following is an example of a Labor Tag 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 Tag’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.",
"codeType": "Tag",
"dateCreated": "2015-04-05T12:59:00Z",
"dateModified": "2015-05-05T16:00:00Z",
"supportedEntities": [
{
"name": "Events",
"isSearchable": true,
"isApplicable": true
},
{
"name": "Locations",
"isSearchable": true,
"isApplicable": false
}
]
}
The following Source Code is used to keep track of people and contributions that came from digital ad campaigns:
{
"codeId": 20615,
"parentCodeId": null,
"name": "Digital ads",
"description": "Used to mark people and contributions retrieved because of digital ad campaigns",
"codeType": "SourceCode",
"dateCreated": "2017-10-05T12:59:00Z",
"dateModified": "2017-10-08T12:00:00Z",
"supportedEntities": null
}
The following list of Codes is formatted for batch operations:
{
"codes": [
{
"parentCodeID": "1019966",
"name": "Labor",
"description": "The tag for describing Labor",
"supportedEntities": [
{
"name": "Contacts",
"isSearchable": true,
"isApplicable": true
},
{
"name": "ActivistCodes",
"isSearchable": true,
"isApplicable": true
}
],
"codeType": "Tag"
},
{
"name": "Volunteers",
"description": "The tab for describing all of our Volunteers",
"supportedEntities": null,
"codeType": "Tag"
}
]
}
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 | A description for this Code, no longer than 200 characters and may be null. |
codeType |
string | Determines whether a Code is a Tag or Source Code. Valid values are Tag and SourceCode . Default is SourceCode . |
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 |
Each Supported Entity has the following properties:
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 |
Each list of Codes has the following properties:
Property | Type | Description |
---|---|---|
code |
array | Required; An array of zero or more Code objects for batch operations. |
Use this endpoint to find Codes available in the current context using a number of filter options.
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 only valid orderby
property is: dateModified
.
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 |
codeType |
query | string | Filters to Codes which match the specified Code Type; must be a Code Type available to the API key, as determined by GET /codeTypes |
$expand |
query | string | Optional; comma delimited list of expansion properties: supportedEntities |
$orderby |
query | string | Optional; sorts results in ascending (asc ) or descending (desc ) order by a comma delimited list of properties: dateModified . Note that a space is required between the property and asc or desc . |
GET /codes?parentCodeId=20513&$expand=supportedEntities&$top=3&codeType=Tag&$orderby=dateModified desc
This endpoint responds with a standard paged response of Codes.
{
"items": [
{
"codeId": 20514,
"parentCodeId": 20513,
"name": "LGBT",
"codeType": "Tag",
"dateCreated": "2015-04-05T12:59:00Z",
"dateModified": "2015-05-01T09:59:00Z",
"supportedEntities": [
{
"name": "Events",
"isSearchable": true,
"isApplicable": true
}
]
},
{
"codeId": 20515,
"parentCodeId": 20513,
"name": "Labor",
"codeType": "Tag",
"dateCreated": "2015-04-05T12:59:00Z",
"dateModified": "2015-05-01T09: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",
"codeType": "Tag",
"dateCreated": "2015-04-05T13:00:00Z",
"dateModified": "2015-05-02T19:59:00Z",
"supportedEntities": [
{
"name": "Events",
"isSearchable": true,
"isApplicable": true
}
]
},
{
"codeId": 20615,
"parentCodeId": 20513,
"name": "Digital ads",
"description": "Used to mark people and contributions retrieved because of digital ad campaigns",
"codeType": "SourceCode",
"dateCreated": "2017-10-05T12:59:00Z",
"dateModified": "2017-11-01T09:32:00Z",
"supportedEntities": null,
}
],
"nextPageLink": "https://api.securevan.com:443/v4/codes?parentCodeId=20513&$expand=supportedEntities&$top=6&$skip=3",
"count": 6
}
Use this endpoint to retrieve an existing Code and its supported Entities.
Parameter | Location | Type | Description |
---|---|---|---|
codeId |
route | int | Required; Unique identifier of an existing Code |
GET /codes/20548
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
.
Use this endpoint to create a new Code in the current context.
Accepts a standard Code object with no read-only values specified. If codeType
is not specified, the default SourceCode
value is assumed. Note that codeType
must be a valid Code Type available for your API key, as determined by GET /codeTypes.
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",
"codeType": "Tag",
"supportedEntities": [
{
"name": "Events",
"isSearchable": true,
"isApplicable": true
},
{
"name": "Locations",
"isSearchable": true,
"isApplicable": true
}
]
}
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.
It is not possible to provide a supportedEntities
list for Tags which includes Entities that are not included in the GET /codes/supportedEntities response. For Source Codes, the supportedEntities
list is ignored, because the list of supported entities is fixed for all Source Codes.
Responses to invalid requests follow the standard for input validation responses.
Use this endpoint to create a batch of new Codes in the current context.
Accepts a standard Codes array with each Code
object
formatted as per POST /codes
. The requirements and limitations
of the endpoint are as described there.
Property | Type | Description |
---|---|---|
code |
array | Required; An array of zero or more Code objects for batch operations. |
In this example, we’re creating two new Codes: one called “Labor” which has a parent code, and one called “Volunteers” which does not.
POST /codes/batch
{
"codes": [
{
"parentCodeID": "1019966",
"name": "Labor",
"description": "The tag for describing Labor",
"supportedEntities": [
{
"name": "Contacts",
"isSearchable": true,
"isApplicable": true
},
{
"name": "ActivistCodes",
"isSearchable": true,
"isApplicable": true
}
],
"codeType": "Tag"
},
{
"name": "Volunteers",
"description": "The tab for describing all of our Volunteers",
"supportedEntities": null,
"codeType": "Tag"
}
]
}
If successful, the endpoint responds with HTTP Status Code 201 Created
and
an array of results, one for each code created or attempted, in the same order
they were given in the request. Each object will contain the ID of the Code,
if successfully created, and any warning or error messages for that Code.
Property | Type | Description |
---|---|---|
codeId |
integer | The ID of the Code, if created successfully. |
message |
string | Any messages or warnings produced during the creation of the Code. |
Example:
[
{
"codeId": 1020112,
"message": "Completed"
},
{
"codeId": 1020113,
"message": "Completed"
}
]
If only some Codes are created, the response will be HTTP Status Code
207 Multi-Status
and the same array of results, which can be inspected for
per-Code details.
If no Codes are created, the response will be HTTP Status Code 404 Not Found
.
Responses to invalid requests follow the standard for input validation responses.
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 editable properties must be
specified otherwise it is assumed they should be removed or set to null.
For example, if the supportedEntities
property is set to null
or []
(an empty array) in the request, all supported Entities are removed from
the Code.
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:
name
description
, if one existsPUT /codes/20547
{
"codeId": 20547,
"parentCodeId": 20515,
"name": "AFL and CIO",
"codeType": "Tag",
"supportedEntities": [
{
"name": "Events",
"isSearchable": true,
"isApplicable": true
},
{
"name": "Locations",
"isSearchable": true,
"isApplicable": true
},
{
"name": "Organizations",
"isSearchable": true,
"isApplicable": false
}
]
}
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.
The codeType
property may not be changed by this route.
It is not possible to provide a supportedEntities
list for Tags which includes Entities that are not included in the GET /codes/supportedEntities response. For Source Codes, the supportedEntities
list is ignored, because the list of supported entities is fixed for all Source Codes.
Responses to invalid requests follow the standard for input validation responses.
Use this endpoint to update the editable properties of a set of existing Codes. For example, you could use this to change the names of Codes, to change several Codes’ parents, or to add or remove the Entities the Codes support.
When constructing your request, note that all editable properties must be
specified otherwise it is assumed they should be removed or set to null.
For example, if the supportedEntities
property is set to null
or []
(an empty array) in JSON specifying a Code, all supported Entities
are removed from that Code.
Accepts a standard Codes array with each Code
object
formatted as per PUT /codes/{codeId}
. The requirements and limitations
of the endpoint are as described there.
Property | Type | Description |
---|---|---|
code |
array | Required; An array of zero or more Code objects for batch operations. |
The following example modifies the Code created in the POST /codes/batch
example by:
name
for the first Codedescription
for both CodesPUT /codes
{
"codes": [
{
"parentCodeID": "1019966",
"codeId": 1020112,
"name": "Unions",
"description": "The tag for describing Labor",
"supportedEntities": [
{
"name": "Contacts",
"isSearchable": true,
"isApplicable": true
},
{
"name": "ActivistCodes",
"isSearchable": true,
"isApplicable": true
}
],
"codeType": "Tag"
},
{
"codeId": 1020113,
"name": "Volunteers",
"description": "The tab for describing all of our Volunteers",
"supportedEntities": [
{
"name": "Organizations",
"isSearchable": true,
"isApplicable": false
}
],
"codeType": "Tag"
}
]
}
If successful, the endpoint responds with HTTP Status Code 200 OK
and
an array of results, one for each code updated or attempted, in the same order
they were given in the request. Each object will contain the ID of the Code,
if successfully updated, and any warning or error messages for that Code.
Property | Type | Description |
---|---|---|
codeId |
integer | The ID of the Code. |
message |
string | Any messages or warnings produced during the update of the Code. |
Example:
[
{
"codeId": 1020112,
"message": "Forbidden"
},
{
"codeId": 1020113,
"message": "Completed"
}
]
If only some Codes are updated, the response will be HTTP Status Code
207 Multi-Status
and the same array of results, which can be inspected for
per-Code details.
If no Codes are updated, the response will be HTTP Status Code 404 Not Found
.
Responses to invalid requests follow the standard for input validation responses.
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.
Parameter | Location | Type | Description |
---|---|---|---|
codeId |
route | int | Required; Unique identifier for an editable Code |
DELETE /codes/20547
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.
Use this endpoint to delete a list of existing Codes. 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.
Accepts a comma-separated array of codeIds.
DELETE /codes
[
12345,
23435,
13355
]
The endpoint responds with HTTP Status Code 200 OK
and
an array of results, one for each code deleted or attempted. Each object
will contain the ID of the Code, if successfully updated, and any warning
or error messages for that Code.
Example:
[
{
"1020112": "This code does not exist or you do not have access to it"
},
{
"1020113": "Completed"
}
]
Responses to invalid requests follow the standard for input validation responses.
Use this endpoint to retrieve all Entity types that Tags can be associated with in this context. Tag support varies by context, but is often one of:
ActivistCodes
— Tags can be applied to Activist Codes in the VAN UIContacts
— Contacts are synonymous with PeopleEvents
— Tags can be applied to EventsLocations
— Tags can be applied to LocationsOrganizations
— Tags can be applied to OrganizationsSurveyQuestions
— Tags can be applied to Survey Questions in the VAN UIThis endpoint does not have relevance for Source Codes, as Source Codes are always applicable to a fixed list of Entities; see the Codes Overview for more details.
This endpoint takes no parameters.
GET /codes/supportedEntities
This endpoint returns an array of strings of Entity types:
[
"Contacts",
"Events",
"Locations"
]
Use this endpoint to determine which code types are available for your API key. At most two types will be available: Tag
and/or SourceCode
. See Codes Overview for more information.
This endpoint takes no parameters.
GET /codeTypes
This endpoint returns an array of strings of Entity types:
[
"Tag",
"SourceCode"
]
A Commitment is a record of a person’s monetary gift with a recurring schedule.
The following is an overview of the Commitment 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.
Property | Type | Description |
---|---|---|
commitmentId |
integer | Read-only; Unique identifier for a Recurring Commitment in this context |
startDate |
datetime | Read-only; Date the Recurring Commitment started |
endDate |
datetime | Read-only; Date the Recurring Commitment ended |
status |
string | The commitment status of the current Recurring Commitment |
amount |
decimal | Monetary amount of each Recurring Commitment |
currency |
integer | Read-only; The currency that is being used for the Recurring Commitment |
frequency |
string | Read-only; The Frequency of each recurring commitment |
nextTransactionDate |
datetime | Date on which the next Recurring Commitment will be processed |
paymentType |
string | Read-only; PaymentType in which the funds will be contributed |
creditCardLast4 |
integer | Read-only; Last 4 digits of the credit card used for the commitment |
ccExpirationYear |
integer | Read-only; Year that the credit card expires |
ccExpirationMonth |
integer | Read-only; Month that the credit card expires |
designationId |
integer | Read-only; The id of the designation which receives this contribution. |
One of
Weekly
EveryTwoWeeks
EveryFourWeeks
Monthly
TwiceMonthly
Quarterly
Annually
TwiceAnnually
One of
Active
InactiveCancelled
Completed
InactiveFailed
Failing
Use this endpoint to update a recurring commitment. You can currently:
Please note that you cannot update a commitment you are attempting to cancel. The cancelation will be processed first, and any other changes will be ignored.
Accepts a standard Commitment object, with any of the not read-only properties set.
To change the next transaction date for a recurring commitment, the new date:
A new amount must be between $0.01 and $999,999.99
Parameter | Location | Type | Description |
---|---|---|---|
commitmentId |
route | integer | Required; Unique commitment identifier available in the current context |
PATCH /commitments/543456
{
"status": "InactiveCancelled"
}
OR
PATCH /commitments/543456
{
"nextTransactionDate": "2020-11-04",
"amount": "35.00"
}
If the specified Commitment does not exist, this endpoint will return an error with a HTTP Status Code 404 Not Found.
If successful, the endpoint responds with HTTP Status Code 200 OK and an updated commitment object.
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.
The following is an example of a contribution.
{
"contributionId": 23453,
"contact": {
"vanId": 10005165
},
"designation": {
"designationId": 18754,
},
"dateReceived": "2013-12-25T12:23:00Z",
"amount": "12.34",
"coverCostsAmount": "2.34",
"status": "Settled",
"paymentType": "Check",
"bankAccount": "PNC Bank Account 1",
"contributionBankAccount": {
"bankAccountId": 9876,
"name": "PNC Bank Account 1"
},
"depositDate": "2013-12-28",
"depositNumber": 3,
"checkDate": "2013-12-25",
"checkNumber": "1222 123",
"contactAttributions": [
{
"vanId": 303,
"amountAttributed": "100.50",
"attributionType": "DefaultAttribution",
"notes": "some notes go here",
"dateThanked": "2013-12-30"
},
{
"vanId": 701,
"amountAttributed": "202.10",
"attributionType": "CorporateMatch",
"notes": "some notes go here",
"dateThanked": "2013-12-30"
},
],
"onlineReferenceNumber": "1230230423",
"pledge": {
"pledgeId": 1035
},
"codes": [
{ "codeId": 12345, "codeName": "Signup Form Source Code" }
],
"directMarketingCode": "Excelsior Consulting",
"dateThanked": "2013-12-30",
"notes": "Processed as part of the Christmas Fundraiser",
"disclosureFieldValues": [
{
"disclosureFieldId": 190,
"disclosureFieldValue": "41",
"designationId": 1121
},
{
"disclosureFieldId": 40,
"disclosureFieldValue": "5",
"designationId": 1121
},
{
"disclosureFieldId": 1001,
"disclosureFieldValue": "John",
"designationId": 1121
}
],
"extendedSourceCode" : {
"extendedSourceCodeId": 12
},
"identifiers": [
{
"type": "ActBlue ID",
"externalId": "123456"
}
],
"financialBatchId": 825,
"processedAmount": 3,
"processedCurrency": "USD",
"acceptedOneTimeAmount": "12.34",
"acceptedRecurringAmount": "5.67",
"selectedOneTimeAmount": "20.00",
"upsellType": "Split",
"isUpsellShown": true,
"isUpsellAccepted": true
}
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.
The required properties are contact
, designation
, dateReceived
, amount
, status
, and paymentType
.
Property | Type | Description |
---|---|---|
contributionId |
int | Read-only; Unique identifier for a Contribution in this context |
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. |
coverCostsAmount |
decimal | Read-only; The amount by which the donor increased their total contribution amount in order to cover costs associated with the online transaction (payment processing fees, shipping fees, administrative costs, etc.). |
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. |
financialBatchId |
int | Optional, the associated Financial Batch. If specified, the Designation of the Financial Batch must match the Designation of this contribution. Financial Batch Manager must be enabled in this context to assign a financialBatchId |
bankAccount |
string | Optional, the associated Bank Account. If no Bank Account with this name is found, a new Bank Account is created. Additional permissions required to create a new Bank Account. Property contributionBankAccount takes precedence if both are used. |
contributionBankAccount |
object | Optional, the associated Bank Account object. Takes precedence over bankAccount if both are used. |
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 Attributions objects associated with the contribution. |
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 | An array of zero or one Code to apply to the contribution. Contributions may not have more than one Code applied, and if a Code is applied, it must be a Source Code. |
directMarketingCode |
string | A direct marketing code. |
dateThanked |
date | The date the contributor was thanked. |
notes |
string | A note describing the contribution. |
disclosureFieldValues |
array | An array of Disclosure Field Value objects associated with the contribution. |
extendedSourceCode |
object | Optional, the Extended Source Code to apply to the contribution. This is only supported in POST and only the extendedSoureCodeId property is required. If this is provided, we’ll look for and apply a matching Source Code to the contribution from a Direct Response Plan segment that the contact is in with a contact history record that has the extended source code. If no matching source code is found, then the POST will fail. |
identifiers |
array | An array of identifier objects |
linkedJointFundraisingContributionId |
int | The ID of the total Joint Fundraising Transfer record, if any. When adding an itemized Joint Fundraising Allocation, use linkedJointFundraisingContributionId to link the allocations to the parent transaction. The Designation for the current Contribution and the Designation for the parent Contribution, indicated by linkedJointFundraisingContributionId , must be identical. Also, the Disclosure Field named “Contribution Type” must have an Option ID corresponding to “Joint Fundraising Allocation”. |
linkedPartnershipContributionId |
int | The ID of the total Partnership Contribution record, if any. When adding an itemized partner Contribution, use linkedPartnershipContributionId to link the itemizations to the parent transaction. The Designation for the current Contribution and the Designation for the parent Contribution, indicated by linkedPartnershipContributionId , must be identical. Also, the Disclosure Field named “Partnership” must have a value of true for this Contribution. |
processedAmount |
decimal | Read-only; The amount of the contribution in the currency used by the contributor. |
processedCurrency |
string | Read-only; The ISO currency code of the currency used by the contributor. |
acceptedOneTimeAmount |
decimal? | Read-only; The one-time contribution amount accepted by the donor in a split upsell scenario. |
acceptedRecurringAmount |
decimal? | Read-only; The recurring contributiom amount accepted by the donor in an upsell scenario. |
selectedOneTimeAmount |
decimal? | Read-only; The one-time contribution amount selected by the donor before being offered an upsell. |
upsellType |
string | Read-only; The type of upsell associated with a given contribution. Split or Switch if there is an associated upsell. null indicates there is no associated upsell. |
isUpsellShown |
bool | Read-only; Indicates whether a donor was offered an upsell when they contributed. |
isUpsellAccepted |
bool | Read-only; Indicates whether a donor accepted an upsell offer when they contributed. |
Property | Type | Description |
---|---|---|
designationId |
int | The id of the designation which receives this contribution. |
Property | Type | Description |
---|---|---|
bankAccountId |
int | Read-only; Unique identifier for a Bank Account in this context. Optional, if specified, the bank account must already exist. |
name |
string | The name of this Bank Account, no longer than 100 characters, optional if bankAccountId is specified. If a bankAccountId is not specified, an attempt is made to look up a Bank Account by this name. If a bankAccountId is not specified and no Bank Account with this name is found, a new Bank Account is created. Additional permissions required to create a new Bank Account. |
Property | Type | Description |
---|---|---|
vanId |
int | Unique identifier for the attributed contact. Represents contacts who acted as fundraisers, rather than contributors. |
amountAttributed |
string | Optional; The amount of the attribution. Values that have more than 2 digits after the decimal point will not be accepted. If no amount is provided, default to contribution amount. |
attributionType |
string | Optional; A string representing the attribution type. See below for valid values of Attribution Type. If no type is provided, default to “DefaultAttribution” type |
notes |
string | Optional; A note describing the attribution. Max length of 100 characters. |
dateThanked |
date | Optional; The date on which the attributed contact was thanked for the contribution. |
One of
BoardMemberGiving
CorporateMatch
DefaultAttribution
DonorAdvisedFund
DonorMatch
FamilyPrivateFoundation
FinanceCommittee
GiftMembership
RaisedContribution
TributeGift
TallyMember
WorkplaceGiving
Property | Type | Description |
---|---|---|
pledgeId |
int | The pledge id of the associated pledge. |
Disclosure Fields exist on a range of objects (e.g. People, Contributions) and are used for Disclosure Reports for FEC and state filing purposes.
Property | Type | Description |
---|---|---|
disclosureFieldId |
int | Identifies the Disclosure Field. Together, the designation id and disclosure field id provide a unique identifier of a Disclosure Field. |
disclosureFieldValue |
string | The value of the Disclosure Field |
designationId |
int | The unique identifier of the Designation of the Disclosure Field |
Used for known external identifiers (e.g., ActBlue ID). External IDs 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. |
externalId |
string | Required; case-insensitive |
One of
Check
MoneyOrder
Cash
CreditCard
InKind
Unknown
ElectronicFundsTransfer
ElectronicPaySystem
PayPal
Stock
ApplePay
Use this endpoint to create a new contribution with the properties provided in the request body.
The body of the request should be a standard Contribution object.
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
, codeId
, or extendedSourceCodeId
) 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.
Retrieve a Contribution record by unique identifier.
Parameter | Location | Type | Description |
---|---|---|---|
contributionId |
route | integer | Unique contribution identifier available in the current context |
GET /contributions/4482
Returns a standard Contribution object, if found.
If the specified Contribution does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Retrieve a Contribution record by an Alternate ID. For example /contributions/onlineReferenceNumber:12345
would retrieve a contribution whose Online Reference Number is 12345.
Parameter | Location | Type | Description |
---|---|---|---|
alternateIdType |
route | string | Required; a known contribution identifier type available in the current context. Currently only onlineReferenceNumber is supported. |
alternateId |
route | string | Required; an alternate identifier, URL encoded |
GET /contributions/onlineReferenceNumber:123
Returns a standard Contribution object, if found.
If the specified Contribution does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Retreive a list of Attribution Types which are enabled on a Designation in the current committee.
GET /contributions/attributionTypes
Returns an array of Attribution Type objects.
Create or update an Attribution record on the given Contribution for a Person.
If there is an existing Attribution for the given Person on the given Contribution, it will be updated to match the Attribution provided with this request. If there is not an existing Attribution, one will be created.
Accepts an Attribution object. The vanId
property of the Attribution object must match the value of the
vanId
parameter provided in the route. If amountAttributed
is not provided, it will default to the remaining amount of the Contribution.
If attributionType
is not provided, it will default to DefaultAttribution
.
Parameter | Location | Type | Description |
---|---|---|---|
contributionId |
route | integer | Unique contribution identifier available in the current context |
vanId |
route | integer | Unique person identifier available in the current context |
PUT /contributions/4482/attributions/215501
{
"vanId": 215501,
"amountAttributed": 100.00,
"attributionType": "BoardMemberGiving",
"dateThanked": "2019-10-08",
"notes": "This will be created or updated"
}
If the specified Contribution or 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
if an existing Attribution has been updated. If a new
Attribution has been created, this endpoint responds with HTTP Status Code 201 Created
.
Responses to invalid requests follow the standard for input validation responses.
Use this endpoint to delete an Attribution for a Person from a Contribution.
Parameter | Location | Type | Description |
---|---|---|---|
contributionId |
route | integer | Unique contribution identifier available in the current context |
vanId |
route | integer | Unique person identifier available in the current context |
DELETE /contributions/4482/attributions/215501
If the specified Contribution or Attribution 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.
Use this endpoint to adjust an existing contribution with the properties provided in the request body. Only contributions processed by EveryAction are supported.
Parameter | Location | Type | Description |
---|---|---|---|
contributionId |
route | integer | Unique contribution identifier available in the current context |
POST /contributions/4482/adjustments
{
"adjustmentType" : "Refund",
"amount" : 10.0,
"datePosted" : "2020-03-31"
}
Currently “Refund” is the only adjustment type supported by the API. Using this adjustment type will issue a refund to the donor.
If successful, the endpoint responds with HTTP Status Code 200 Ok
and the following is an example of json object returned in the response body.
{
"contributionId" : 123,
"originalAmount" : 20.00,
"remainingAmount" : 10.00,
"dateAdjusted": "2020-03-04"
}
Error Response
If the specified Contribution does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Any vendor error will result in 500 Internal Server Error
.
A Custom Field represents structured data about a person or other object in VAN, configured by a VAN user.
A Custom Contact Field is a Custom Field applied to People.
A Custom Contribution Field is a Custom Field applied to Contributions.
These are the only types of Custom Fields available via the API.
Note: Custom Contact Fields may only be assigned to Contacts 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:
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: Note: Only Custom Contact Fields may have parented custom fields.
{
"customFieldId": 157,
"customFieldParentId": null,
"customFieldName": "Education level",
"customFieldGroupId": 52,
"customFieldGroupName": "Education",
"customFieldGroupType": "Contacts",
"customFieldTypeId": "S",
"isEditable": true,
"isExportable": false,
"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
}
]
}
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 |
customFieldGroupType |
string | The type of Custom Field Group (must be Contacts or Contributions) |
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 |
isExportable |
boolean | Indicates whether or not the Custom Field may be included in an Export Job |
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) |
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) |
Use this endpoint to retrieve all Custom Fields that are available in the current context.
Parameter | Location | Type | Description |
---|---|---|---|
customFieldsGroupType |
query | string | Optional; filter by the specified Custom Field Group Type. Default value is Contacts . If provided, must be Contacts or Contributions . |
GET /customFields?customFieldsGroupType=Contacts
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",
"customFieldGroupType": "Contacts",
"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",
"customFieldGroupType": "Contacts",
"customFieldTypeId": "B",
"isEditable": true,
"maxTextboxCharacters": null,
"availableValues": null
},
{
"customFieldId": 206,
"customFieldParentId": null,
"customFieldName": "Stipend amount",
"customFieldGroupId": 55,
"customFieldGroupName": "College Student Organizing",
"customFieldGroupType": "Contacts",
"customFieldTypeId": "M",
"isEditable": false,
"maxTextboxCharacters": null,
"availableValues": null
},
{
"customFieldId": 207,
"customFieldParentId": null,
"customFieldName": "Graduation date",
"customFieldGroupId": 55,
"customFieldGroupName": "College Student Organizing",
"customFieldGroupType": "Contacts",
"customFieldTypeId": "D",
"isEditable": true,
"maxTextboxCharacters": null,
"availableValues": null
},
{
"customFieldId": 208,
"customFieldParentId": null,
"customFieldName": "Department of study",
"customFieldGroupId": 55,
"customFieldGroupName": "College Student Organizing",
"customFieldGroupType": "Contacts",
"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",
"customFieldGroupType": "Contacts",
"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",
"customFieldGroupType": "Contacts",
"customFieldTypeId": "N",
"isEditable": true,
"maxTextboxCharacters": null,
"availableValues": null
},
{
"customFieldId": 211,
"customFieldParentId": null,
"customFieldName": "Name of high school",
"customFieldGroupId": 55,
"customFieldGroupName": "College Student Organizing",
"customFieldGroupType": "Contacts",
"customFieldTypeId": "T",
"isEditable": true,
"maxTextboxCharacters": 75,
"availableValues": null
}
]
Use this endpoint to retrieve information about a specific Custom Field available in the current context.
This endpoint takes the following parameter:
Parameter | Location | Type | Description |
---|---|---|---|
customFieldId |
route | int | Unique identifier for a specific Custom Field. |
GET /customFields/165
A standard Custom Field object, if found.
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.
The following is an example of designation
{
"designationId": 123456789,
"name": "Jane for Congress Committee"
}
The following is an overview of the Designation object.
Available properties
Property | Type | Description |
---|---|---|
designationId |
int | Unique identifier for a Designation in this context. |
name |
string | A name for this designation |
Use this endpoint to get designation IDs and names
This endpoint takes no parameters
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"
}
]
}
A Disbursement is a record of an expenditure made by your organization. They must be linked to both the Person that received the expenditure, and the Designation corresponding to the disbursement. Disbursements can have Codes applied to them.
The following is an example of a disbursement.
{
"disbursementId": 23453,
"contact": {
"vanId": 10005444
},
"designation": {
"designationId": 18754,
},
"dateIssued": "2013-12-25T12:23:00Z",
"amount": "12.34",
"batchCode": "123",
"checkDate": "2013-12-25",
"checkNumber": "1222 123",
"codes": [
{ "codeId": 12345 }
],
"notes": "Expense for the Christmas Fundraiser",
"disclosureFieldValues": [
{
"disclosureFieldId": 30000,
"disclosureFieldValue": "30060",
"designationId": 1121
},
{
"disclosureFieldId": 30008,
"disclosureFieldValue": "2018",
"designationId": 1121
}
]
}
The following is an overview of the Disbursement 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.
If any of the specified ids (vanId
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.
The required properties are contact
, designation
, dateIssued
, and amount
.
Property | Type | Description |
---|---|---|
disbursementId |
int | Read-only; Unique identifier for a disbursement in this context |
contact |
object | The Person who is associated to this disbursement. |
designation |
object | The Designation which will receive this disbursement. |
dateIssued |
datetime | The date and time of this disbursement. |
amount |
decimal | The amount of the disbursement. Non-positive values, and values that have more than 2 digits after the decimal point, will not be accepted. |
checkDate |
date | The date of the check. |
checkNumber |
string | The number of the check. |
codes |
array | An array of zero or one Code to apply to the disbursement. Disbursements may not have more than one Code applied, and if a Code is applied, it must be a Source Code. |
notes |
string | A note describing the disbursement. |
disclosureFieldValues |
array | An array of Disclosure Field Value objects associated with the disbursement. |
linkedCreditCardPaymentDisbursementId |
int | The ID of the total Credit Card Payment record, if any. When disclosing a payment made to a credit card, use linkedCreditCardPaymentDisbursementId to link disbursements itemizing each purchase made to the parent Disbursement with which the bill was paid. Must be in the same Designation as the Disbursement in question. Also, the Disclosure Field named “ExpenseSubType” must have an Option ID corresponding to “Credit Card/Paycheck Item” for this Disbursement. |
linkedReimbursementDisbursementId |
int | The ID of the total Reimbursement Payment record, if any. When reimbursing an individual or organization for purchases made on your behalf, use linkedReimbursementDisbursementId to link disbursements itemizing each purchase to the parent Disbursement in which they are reimbursed. Must be in the same Designation as the Disbursement in question. Also, the Disclosure Field named “ExpenseSubType” must have an Option ID corresponding to “Reimbursement Item” for this Disbursement. |
Property | Type | Description |
---|---|---|
designationId |
int | The id of the Designation which receives this disbursement. |
Property | Type | Description |
---|---|---|
disclosureFieldId |
int | Identifies the disclosure field. Together, the designation id and disclosure field id provide a unique identifier of a disclosure field. |
disclosureFieldValue |
string | The value of the Dislosure Field |
designationId |
int | The unique identifier of the Designation which will receive the disbursement |
Use this endpoint to create or update a disbursement with the properties provided in the request body.
The body of the request should be a standard Disbursement object.
If successful, the endpoint responds with the body of the submitted disbursement, along with HTTP Status Code 201 Created
if a new Disbursement is created, or a 200 OK
if an existing Disbursement was updated.
Retrieve a Disbursement record by unique identifier.
Parameter | Location | Type | Description |
---|---|---|---|
disbursementId |
route | integer | Unique disbursement identifier available in the current context |
GET /disbursements/4482
Returns a standard Disbursement object, if found.
If the specified Disbursement does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
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 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"
}
]
}
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 |
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) |
Use this endpoint to retrieve all District Fields
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
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,
}
]
}
Use this endpoint to get full details for a district field
The request has no parameters
GET /districtFields/12345
The Targeted Email endpoint allows you to pull meta data about your email messages sent by Targeted Email. The endpoint allows you to see email interaction data, resulting contribution totals, and form submissions resulting from the email message.
Note that it takes some time for the system to aggregate opens and click-throughs, so data can be delayed up to 15 minutes.
The following is an example of a Master Batch Email. Email of this type have the following rules:
{
"foreignMessageId": "Bph3Qyl3tFUzD89NbAQMM72",
"name": "Email Round One",
"createdBy": "John Smith",
"dateCreated": "2018-04-27T15:50:00Z",
"dateScheduled": "2018-04-27T16:01:00Z",
"campaignID": 0,
"dateModified": "2018-09-03T16:56:38.613Z",
"emailMessageContent": [
{
"name": "Fund Raising Survey",
"senderDisplayName": "John Smith",
"senderEmailAddress": "jsmith@ngpvan.com",
"createdBy": "John Smith",
"dateCreated": "2018-04-27T15:50:00Z",
"emailMessageContentDistributions": {
"dateSent": "2018-04-27T16:01:00Z",
"recipientCount": 0,
"openCount": 0,
"linksClickedCount": 0,
"unsubscribeCount": 0,
"bounceCount": 0,
"contributionTotal": 0.0,
"formSubmissionCount": 0,
"contributionCount": 0
}
}
]
}
Use this endpoint to retrieve all emails that are available in the current context.
The only valid orderby
property is: dateModified
.
Parameter | Location | Type | Description |
---|---|---|---|
$orderby |
query | string | Optional; sorts results in ascending (asc ) or descending (desc ) order by a comma delimited list of properties: dateModified . Note that a space is required between the property and asc or desc |
GET /email/messages
Emails ordered by dateModified
in ascending order
GET /email/messages?$orderby=dateModified asc
Emails ordered by dateModified
in descending order
GET /email/messages?$orderby=dateModified desc
This endpoint responds with an array of standard Email objects.
Use this endpoint to retrieve information about a specific Email available in the current context.
Parameter | Location | Type | Description |
---|---|---|---|
emailId |
route | string | String identifier for a specific Email, corresponds to ForeignMessageId from email messages |
$expand |
query | string | Optional; comma delimited list of expansion properties: emailmessagecontent , emailmessagecontentdistributions |
GET /email/message/Bph3Qyl3tFUzD89NbAQMM72
A standard Email object, if found.
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.
The following is an example of a Phone Bank Event Type. Events of this type have the following rules:
#C6AFDA
) in the VAN UI{
"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
},
"isSharedWithMasterCommitteeByDefault": false,
"isSharedWithChildCommitteesByDefault": true
}
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 |
isSharedWithMasterCommitteeByDefault |
bool | Indicates that Events of this Event Type, if created in a child committee, are automatically shared with the parent (master) committee |
isSharedWithChildCommitteesByDefault |
bool | Indicates that Events of this Event Type, if created in a parent (master) committee, are automatically shared with all of its child committees |
Use this endpoint to retrieve all Event Types that are available in the current context.
This endpoint takes no parameters.
GET /events/types
This endpoint responds with an array of standard Event Type objects.
Use this endpoint to retrieve information about a specific Event Type available in the current context.
Parameter | Location | Type | Description |
---|---|---|---|
eventTypeId |
route | int | Unique identifier for a specific Event Type |
GET /events/eventTypes/234956
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
.
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.
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 1900 → 01 Jan 2100).
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.
String properties of Events and related objects use standard input validation rules.
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.
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",
"codeType": "Tag",
"dateCreated": "2015-04-05T13:00:00Z",
"supportedEntities": null
},
{
"codeId": 20518,
"parentCodeId": 20513,
"name": "Youth",
"codeType": "Tag",
"dateCreated": "2015-04-05T13:02:00Z",
"supportedEntities": null
},
{
"codeId": 20615,
"parentCodeId": null,
"name": "Digital Ads",
"codeType": "Sourcecode",
"dateCreated": "2017-10-01T13: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.
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 internal-facing description for this Event, no longer than 500 characters. This corresponds to a field used by staff to track event information; it is not a public-facing description for attendees. |
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 Codes that are applied to this Event for organizational purposes. Note that at most one Source Code, and any number of Tags, may be applied to an Event. |
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 |
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 |
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 |
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 |
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:
eventType
of the passed event must support batch linkingvoterRegistrationBatchId
must already exist, must be available to the current user, and must not already be linked to another eventProperty | Type | Description |
---|---|---|
voterRegistrationBatchId |
int | Unique identifier for the Voter Registration Batch in question |
Use this endpoint to find Events available in the current context using a number of filter options.
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
. 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 |
createdByCommitteeId |
query | int | Filters Events to those which were created by the specified CommitteeID |
$expand |
query | string | Optional; comma delimited list of expansion properties: locations , codes , shifts , roles , notes |
GET /events?startingAfter=2015-05-31&$expand=shifts&$top=2&districtFieldValue=003
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
}
Use this endpoint to retrieve the details of a specific Event.
Use the Signups endpoint to retrieve a list of the Event’s participants.
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
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
.
Changes the status of an Event. Note: only the status
property may be patched.
Parameter | Location | Type | Description |
---|---|---|---|
eventId |
route | int | Required; Unique identifier of the Event to be updated |
recurrenceType |
query | string | Optional; the Events in a recurring series to update. Must be one of ThisEvent , ThisAndFutureEvents , or AllEvents . Default, if not supplied, is ThisEvent . |
Property | Type | Description |
---|---|---|
eventId |
int | Required; Unique identifier of the event to be updated |
isActive |
bool | Required; If true , will restore a previously deleted Event; If false , the result will effectively be the same as if the Events DELETE API method had been called. |
PATCH /events/234234
{
"eventId": 234234
"isActive": true
}
If the specified Event does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
If isActive
is true
but specified Event 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.
Use this endpoint to create a new Event.
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"
}
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.
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.
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"
}
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.
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.
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:
name
and shortName
locations
(removing locationId
273 and adding locationId
272)codes
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"
}
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.
Use this endpoint to delete an existing Event and its related Signups. 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.
Parameter | Location | Type | Description |
---|---|---|---|
eventId |
route | int | Required; Unique identifier for an editable Event |
DELETE /events/234234
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.
An Export Job is a process which provides data in bulk. Export Jobs result in the creation of a CSV file, which API consumers may download until the file expires. Because an Export Job may take some time to complete, API consumers are required to provide a webhook where the consumer will be notified once the job is complete.
Most Export jobs have a 100MB file size limit, after which the file will be truncated. Export jobs only containing VANIDs may export up to 10 million records.
The following is an example of a completed Export Job.
{
"exportJobId": 999888,
"exportJobGuid": "7B623929-05DA-4356-BF30-EF7D1BB0248C",
"savedListId": 1234,
"webhookUrl": "https://webhook.example.org/completedExportJobs",
"downloadUrl": "https://ngpvan.blob.core.windows.net/completed-export-jobs/7B623929-05DA-4356-BF30-EF7D1BB0248C_2017-01-01T12:00:00.csv",
"status": "Completed",
"type": 777,
"dateExpired": "2017-01-04T12:00:00Z",
"errorCode": null,
"surveyQuestions": [ { "surveyQuestionId": 1234 } ],
"activistCodes": [ { "activistCodeId": 4567 } ],
"customFields": [ { "customFieldId": 5678 } ],
"districtFields": [ { "districtFieldId": 10 } ]
}
Property | Type | Description |
---|---|---|
exportJobId |
int | Read-only; Unique identifier for an Export Job |
exportJobGuid |
string | Read-only; Globally unique identifier for an Export Job |
savedListId |
int | The Saved List containing People who are to be exported. This Saved List must be available to the API - i.e. it must be available via GET /savedLists. |
webhookUrl |
string | The URL to be notified when the Export Job has completed |
downloadUrl |
string | Read-only; The URL where the completed Export Job may be downloaded. Will be null unless status is Completed . |
status |
string | Read-only; The status of the Export Job; may be Requested , Pending , Completed , or Error |
type |
int | The type of Export Job, indicating the columns to provide about the People in the Saved List. Contact us to determine the appropriate type. Note that while the list of columns provided with an Export Job type is static, some columns may be blank in certain contexts due to lack of availability. |
dateExpired |
datetime | Read-only; The date when the download URL expires. |
errorCode |
string | Read-only; a reference for any error which occurred during the processing of the Export Job. Will be null unless status is Error . |
surveyQuestions |
array | Write-only; an array of objects, each containing a surveyQuestionId indicating a Survey Question whose response should be added to the file for each person in the Export Job. The column heading for these responses will be of the form SurveyQuestion_1234 , and the value in each row will be of the form 2345 , where 1234 and 2345 are the Survey Question ID and Survey Question Response ID, respectively. See Note below for important caveats. |
activistCodes |
array | Write-only; an array of objects, each containing an activistCodeId indicating an Activist Code whose response should be added to the file for each person in the Export Job. The column heading for these responses will be of the form ActivistCode_4567 , where 4567 is the Activist Code ID; for those people who have had the Activist Code applied, the value in each row will be 4567 , and for those who have not had it applied, the value will be blank. See Note below for important caveats. |
customFields |
array | Write-only; an array of objects, each containing a customFieldId indicating a Custom Field whose value should be added to the file for each person in the Export Job. The column heading for these responses will be of the form CustomField_5678 , where 5678 is the Custom Field ID. Custom Fields requested via an export job must be marked as exportable. See Note below for important caveats. |
districtFields |
array | Write-only; an array of objects, each containing a districtFieldId indicating a District Field whose value should be added to the file for each person in the Export Job. The column heading for these responses will be of the form DistrictField_10 , and the value in each row will be of the form 111 , where 10 and 111 indicate the District Field ID and District Field Value ID, respectively. See Note below for important caveats. |
Note about Survey Questions, Activist Codes, Custom Fields and District Fields
Please note the following caveats about using these properties:
For example, it is valid to request three Survey Questions and three Activist Codes, but it is not valid to request six Activist Codes in a single Export Job; or to request three Survey Questions, three Activist Codes, three Custom Fields, and three District Fields in a single Export Job.
Retrieve the Export Job Types available for the current key.
GET /exportJobTypes
{
"items": [
{
"exportJobTypeId": 4,
"name": "SavedListExport"
}
],
"nextPageLink": null,
"count": 1
}
Create a new Export Job
POST /exportJobs
{
"savedListId": 1234,
"type": 777,
"webhookUrl": "https://webhook.example.org/completedExportJobs"
}
The parameters for creating an Export Job are as follows:
Parameter | Type | Description |
---|---|---|
savedListId |
int | The list of People who are to be exported |
type |
int | The type of export to prepare. Must be an Export Job Type available via GET /exportJobTypes. |
webhookUrl |
string | The URL to be notified when the Export Job has completed |
An Export Job object, indicating the ID of the Export Job as well as the status of the job.
When the job completes, the JSON-formatted Export Job object will be POSTed to the webhookUrl
indicated above.
Retrieve a single Export Job.
Parameter | Location | Type | Description |
---|---|---|---|
exportJobId |
route | int | Required; Unique identifier of the Export Job |
GET /exportJobs/123
The Export Job object, indicating the ID of the Export Job as well as the current status of the job.
Extended Source Codes help you track more granular attributes about the mailing or donor such as RFM values or donor level.
New Extended Source Codes can be created in Bulk Upload - Apply Direct Response. They can be then associated with contributions through POST /contributions.
The following is an example of an Extended Source Code called AXY10892323IDFEN23819.
{
"extendedSourceCodeId": 18,
"extendedSourceCodeName": "AXY10892323IDFEN23819",
"createdBy": {
"userId": 111222,
"firstName": "Frances",
"lastName": "Perkins"
},
"dateCreated": "2020-04-28T16:13:00Z",
"modifiedBy": null,
"dateModified": null
}
Property | Type | Description |
---|---|---|
extendedSourceCodeId |
int | A unique identifier for an Extended Source Code in this context |
extendedSourceCodeName |
string | A name for this Extended Source Code. Must be alphanumeric and no longer than 20 characters |
createdBy |
object | An object containing a userId property indicating the ID of the VAN User who created this extended source code |
dateCreated |
date | The date the extended source code was created |
modifiedBy |
object | An object containing a userId property indicating the ID of the VAN User who last modified this extended source code |
dateModified |
date | The date the extended source code was last modified |
Use this endpoint to find Extended Source Codes available in the current context.
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 |
---|---|---|---|
vanId |
query | int | Optional; Filter extended source codes to those associated with the given contact. |
extendedSourceCodeName |
query | string | Optional; Filters to Extended Source Codes with names that contain the given input |
GET /codes/extendedSourceCodes?extendedSourceCodeName=AXY1
This endpoint responds with a standard paged response of Extended Source Codes.
{
"items": [
{
"extendedSourceCodeId": 18,
"extendedSourceCodeName": "AXY10892323IDFEN23819",
"createdBy": 459,
"dateCreated": "2020-04-28T16:13:00Z",
"modifiedBy": null,
"dateModified": null
},
],
"nextPageLink": null,
"count": 1
}
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.
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.
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. |
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. |
Property | Type | Description |
---|---|---|
fileName |
string | Required; Name of the delimited file within the zip file accessible by sourceUrl (e.g., MyScoreResults.csv ). |
hasHeader |
bool | Optional; Indicates that the first line of the file should be skipped. A header row in the file will be not be used; column names are determined by the required columns array and the order the columns appear in the file. Defaults to false . |
sourceUrl |
string | Required; URL at which a zip file containing fileName can be accessed. The following URL schemes (“protocols”) are supported: SFTP, FTPS, HTTPS. If authentication is required, the username and password should be included in the URL (e.g., sftp://user:password@foo.bar.us/my_camp_score.zip). |
columnDelimiter |
string | Optional; Character that separates each each column; one of: Csv → comma (,) separated values, Tab → Tab separated values, Pipe → pipe (|) separated values. Defaults to CSV . |
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. |
A column name
must be present for every column in the uploaded file, listed in the order in which they appear in the file from left to right.
Property | Type | Description |
---|---|---|
name |
string | Required; A column’s unique name that can be referenced in actions (e.g., VanID). The name can consist of alphanumeric characters only; no spaces or punctuation are permitted. |
Each Job Action Type has different supported and required for the Action property. See the individual Action Type docs for more info.
Currently supported actions include:
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 , https://mydomain.com/vanjobs/notify/myInternalJobId ) |
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) |
This is the Score
Action Type.
Property | Type | Description |
---|---|---|
actionType |
string | Required; This must be set to Score for Score Load jobs |
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, StateFileID → Available in AVEV data uploads |
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. |
approvalCriteria |
object | Optional; A Score Approval Criteria object for automatically approving the score. Only available to API keys with permission to automatically approve scores. |
A set of criteria which may be used to auto-approve scores.
Property | Type | Description |
---|---|---|
average |
float | The average of the values in the score column. Must be a number between the maximum and minimum possible acceptable values of the score. |
tolerance |
float | The tolerance for approval. The API will compute the actual average of score values in the file; if the actual average is in the range [average - tolerance, average + tolerance] , then the score will be automatically approved. Note that tolerance must be less than 10% of the difference between the maximum and minimum possible acceptable values of the score. |
This is the AVEVDataFile
Action Type. File uploads for Absentee Vote and Early Vote data have a specific set of expected columns. All of the Required columns must be present but their values can be blank. The columns must be named exactly as specified, including casing, and in the order specified. Exactly one of the VanID
or StateFileID
columns must be present.
Column | Type | Description |
---|---|---|
VanID |
int | Required; The VoterFile VANID of the VoterFile record. All AVEV data files require either a VanID or a StateFileID, but not both. |
StateFileID |
int | Required; The unique identifier for the record on the state file. All AVEV data files require either a VanID or a StateFileID, but not both. |
RequestReceived |
date | Required; The date the absentee ballot request was received. |
BallotMailed |
date | Required; The date the absentee ballot was mailed. |
BallotReceived |
date | Required; The date the completed ballot was received. |
EarlyVoted |
date | Required; The date that the person early voted. |
BallotParty |
string | Required; A one- or two-character code corresponding to the party the ballot belongs to. |
BallotCancelled |
date | Required; The date the absentee ballot was cancelled. |
ApplicationMailed |
date | Required; The date the absentee application was mailed. |
GOTVVoted |
date | Required; The date the person voted on election day. |
DateApplicationReceived |
date | Required; The date the absentee application was received. |
BallotReturnStatus |
int | Optional; ID for the ballot return status |
BallotType |
int | Optional; ID for the ballot type |
BallotRequestType |
int | Optional; ID for the ballot request type |
BallotAddress1 |
string | Optional; First line of a Street Address (up to 40 characters) |
BallotAddress2 |
string | Optional; Second line of a Street Address (up to 40 characters) |
BallotAddress3 |
string | Optional; Third line of a Street Address (up to 40 characters) |
BallotCity |
string | Optional; City or Town (up to 25 characters) |
BallotState |
string | Optional; Two-character state code (e.g. MN, FL, etc) |
BallotZip9 |
string | Optional; ZIP+4 for this address (up to 10 characters) |
BallotCountry |
string | Optional; A two-character ISO country code that is supported by your VAN context (e.g., US) |
{
"description": "Load AV/EV Data",
"listeners": [{"type": "email", "value": "your email" }],
"file":
{
"columnDelimiter": "Csv",
"fileName": "avev-file.csv",
"sourceUrl": "https://example.org/avev-file.zip",
"hasHeader": false,
"columns": [
{ "name": "VANID" },
{ "name": "RequestReceived" },
{ "name": "BallotMailed" },
{ "name": "BallotReceived" },
{ "name": "EarlyVoted" },
{ "name": "BallotParty" },
{ "name": "BallotCancelled" },
{ "name": "ApplicationMailed" },
{ "name": "GOTVVoted" },
{ "name": "DateApplicationReceived" },
{ "name": "BallotReturnStatus" },
{ "name": "BallotType"},
{ "name": "BallotRequestType"},
{ "name": "BallotAddress1"},
{ "name": "BallotAddress2"},
{ "name": "BallotAddress3"},
{ "name": "BallotCity"},
{ "name": "BallotState"},
{ "name": "BallotZip9"},
{ "name": "BallotCountry"}
]
},
"actions":
[
{
"actionType": "AVEVDataFile"
}
]
}
This is the LoadSavedListFile
Action Type. This method creates a new Saved List and loads it with the specified data.
It may optionally overwrite an existing Saved List to which the user has access.
Property | Type | Description |
---|---|---|
action |
string | Required; This must be LoadSavedListFile . |
listName |
string | Required; The user-facing name of the Saved List. Must be unique within the target folder. Must be fewer than 50 characters. |
listDescription |
string | Optional; The user-facing description of the Saved List. Must be fewer than 250 characters. |
personIdType |
string | Required; This must be VANID . |
personIdColumn |
string | Required; This must be VANID . |
folderId |
int | Required; The folder to store the Saved List in. The campaign or organization must have shared this folder to the API User and marked it as an API-writable folder. |
overwriteExistingListId |
int | Optional; If specified, overwrites the specified Saved List rather than creating a new one, replacing Name and Description. The list must have been created by the API User to overwrite it. |
Successful list loads will send a standard webhook to the configured HTTP listener, if any. List-specific data will be provided in the savedList
property.
Property | Type | Description |
---|---|---|
savedListId |
int | The ID of the Saved List that was created or overwritten. |
originalRowCount |
string | The count of rows that were in the source file, before validation, duplicate removal, and access checks. |
matchedRowsCount |
string | The count of rows that were loaded into the Saved List, after validation, duplicate removal, and access checks. |
unmatchedRowsCount |
string | The count of rows that were not loaded into the Saved List, due to failing validation, duplicate removal, or access checks. |
Example:
{
"savedList": {
"savedListId": 2345,
"originalRowCount": 500,
"matchedRowsCount": 473,
"unmatchedRowsCount": 27
},
"message": "Saved List File loaded",
"description": "Saved List Load",
"status": "Successful"
}
In this example, score 112233
will be loaded from the second column of haberdasher.csv
, and the resulting Score Update must be approved separately. However, score 112234
will be loaded from the third column; the API will calculate the average of this column, and if the observed average is between 73.9
and 76.5
(i.e., the average
of 75.2 plus or minus the tolerance
of 1.3), then the Score Update will be set to status Approved
with no further action needed. If the API computes an average for the third column which is less than 73.9
or great than 76.5
, then the resulting Score Update must be approved separately, as is the case with score 112233
.
POST /fileLoadingJobs
{
"description": "Load habberdasher score",
"file": {
"columnDelimiter": "Csv",
"columns": [
{"name": "hatWearerId"},
{"name": "hatWearingScore"},
{"name": "needsAnotherHatScore"}
],
"fileName": "haberdashery.csv",
"hasHeader": true,
"sourceUrl": "sftp://keep:yourHatOn@ftp.headpieces.example.org/haberdasher.csv.zip"
},
"actions": [
{
"actionType": "score",
"personIdColumn": "hatWearerId",
"personIdType": "VANID",
"scoreColumn": "hatWearingScore",
"scoreId": 112233,
},
{
"actionType": "score",
"personIdColumn": "hatWearerId",
"personIdType": "VANID",
"scoreColumn": "needsAnotherHatScore",
"scoreId": 112234,
"approvalCriteria": {
"average": 75.2,
"tolerance": 1.3
}
}
],
"listeners": [
{
"type": "URL",
"value": "https://haberdashery.example.org/listener"
},
{
"type": "EMAIL",
"value": "support@haberdashery.com"
}
]
}
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"
}
A successful POST returns the jobId
of the File Loading Job.
{
"jobId": 998877
}
This endpoint returns status and metadata about an existing File Loading Job, which is specified by the unique identifier jobId
. The jobId
is provided as the response to a POST
request to create a File Loading Job.
GET /fileLoadingJobs/12345
Parameter | Location | Type | Description |
---|---|---|---|
jobId |
route | int | unique identifier for a FileLoadingJob |
Returns metadata about a FileLoadingJob object, if found.
POST /fileLoadingJobs
{
"jobId": 998877,
"actions": [
{
"actionType": "score",
"personIdColumn": "hatWearerId",
"personIdType": "VANID",
"scoreColumn": "hatWearingScore",
"scoreId": 112233
},
{
"actionType": "score",
"personIdColumn": "hatWearerId",
"personIdType": "VANID",
"scoreColumn": "needsAnotherHatScore",
"scoreId": 112234,
"approvalCriteria": {
"average": 75.2,
"tolerance": 1.3
}
],
"description": "Load habberdasher score",
"file": {
"columnDelimiter": "Csv",
"columns": [
{"name": "hatWearerId"},
{"name": "hatWearingScore"},
{"name": "needsAnotherHatScore"}
],
"fileName": "haberdashery.csv",
"hasHeader": true,
"sourceUrl": "sftp://keep:yourHatOn@ftp.headpieces.example.org/haberdasher.csv.zip"
},
"listeners": null,
"interventionCallbackUrl": null,
"invalidRowsFileUrl": null
}
If the specified jobId
is inaccessible or does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Financial Batches are used to batch contributions in order to make it easy for accounting teams to reconcile their data against the organization’s bank statements.
Property | Type | Description |
---|---|---|
financialBatchId |
int | Read-only; Unique identifier for a Financial Batch in this context. |
financialBatchNumber |
long | Required; User-specified identifier for this batch. Must be unique within this context. |
designationId |
int | Required; Designation to associate this Financial Batch with. |
financialBatchName |
string | User-specified name for this batch. Must be unique within this context. Must not be Unassigned |
expectedContributionCount |
int | If set, the number of contributions expected for this batch. The total count of contributions in the batch must match the expected count in order to close the batch. |
expectedContributionTotalAmount |
decimal | If set, the total monetary amount of contributions expected for this batch. The total amount of contributions in the batch must match the expected amount in order to close the batch. |
isOpen |
bool | Read-only; A batch may have a status of open or closed. If true , the batch is currently open and can have contributions added to it. If false , the batch is closed and may not have contributions added to it. |
dateOpened |
date | Read-only; If set, this is the date the batch was opened. |
dateClosed |
date | Read-only; If set, this is the date the batch was closed. |
isAutoGenerated |
bool | Read-only; If true , this is a system-generated batch, and contributions cannot be manually associated with it. |
bankAccountId |
int | Read-only; If set, the bank account associated with the batch. |
dateDeposited |
date | Read-only; If set, the deposit date recorded on the batch. |
depositNumber |
int | Read-only; If set, the deposit number recorded on the batch. |
checkDate |
date | Read-only; If set, the check date recorded on the batch. |
checkNumber |
int | Read-only; If set, the check number recorded on the batch. |
Search for Financial Batches, with optional filtering. All query-string filters are optional.
Parameter | Location | Type | Description |
---|---|---|---|
searchKeyword |
query | string | Filter to batches whose names contain this text. |
includeUnassigned |
query | bool | If true , include the special Unassigned batch in the response. Default is true . |
includeAllAutoGenerated |
query | bool | If true , includes autogenerated batches. Default is true . |
includeAllStatuses |
query | bool | If true , includes closed batches. Default is true . |
GET /financialBatches
{
"items": [
{
"financialBatchId": 825,
"financialBatchNumber": 8675308,
"financialBatchName": "Example Batch",
"designationId": 122,
"expectedContributionCount": 10,
"expectedContributionTotalAmount": 500.0000,
"bankAccountId": null,
"dateDeposited": null,
"depositNumber": null,
"checkDate": null,
"checkNumber": null,
"isOpen": true,
"dateOpened": "2019-08-01T10:00:00Z",
"dateClosed": null,
"isAutoGenerated": false
}
]
}
Retrieve a single Financial Batch.
Parameter | Location | Type | Description |
---|---|---|---|
financialBatchId |
route | int | Required; Unique identifier of the Financial Batch |
GET /financialBatches/825
{
"financialBatchId": 825,
"financialBatchNumber": 8675308,
"financialBatchName": "Example Batch",
"designationId": 122,
"expectedContributionCount": 10,
"expectedContributionTotalAmount": 500.0000,
"bankAccountId": null,
"dateDeposited": null,
"depositNumber": null,
"checkDate": null,
"checkNumber": null,
"isOpen": true,
"dateOpened": "2019-08-01T10:00:00Z",
"dateClosed": null,
"isAutoGenerated": false
}
If the specified Financial Batch does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found.
Create a Financial Batch.
POST /financialBatches
{
"financialBatchNumber": 8675308,
"financialBatchName": "Example Batch",
"designationId": 122,
"expectedContributionCount": 10,
"expectedContributionTotalAmount": 500.00
}
An object containing the new Financial Batch’s ID.
A Folder is a container for Saved List. A folder is available to an API key only if: a) the folder was created by the API key or was shared with the API key; and b) the folder was created by the API key’s committee.
Use this endpoint to retrieve metadata about available folders.
This endpoint accepts standard pagination parameters and returns a standard paginated response.
A paginated list of Folder objects.
Use this endpoint to get full details for a folder
The request has no parameters
GET /folders/123456
A Folder
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.
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"
}
}
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 |
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 ) |
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) |
Use this endpoint to find Locations available in the current context using a number of filter options.
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
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
}
Use this endpoint to retrieve the details of a specific Location.
Parameter | Location | Type | Description |
---|---|---|---|
locationid |
route | int | Required; Unique identifier of a Location to be retrieved |
GET /locations/272
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
.
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:
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 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
city
and stateOrProvince
), a match will be attempted based on Street Number, Street Name, Apartment Number, and ZIP5Non-US contexts match on exact name and parsed address.
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"
}
}
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.
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).
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"
}
}
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.
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.
Parameter | Location | Type | Description |
---|---|---|---|
locationId |
route | int | Required; Unique identifier for an editable Location |
DELETE /locations/272
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.
A MiniVAN Export contains a set of records from the VoterFile or MyCampaign which has been exported to MiniVAN for use in canvassing efforts.
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"
}
]
}
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 |
Use this endpoint to retrieve all available MiniVAN Exports.
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.
The only valid expansion property is: canvassers
.
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 |
$expand |
query | string | Optional; comma delimited list of expansion properties: canvassers |
GET /minivanExports?generatedAfter=2012-10-01&generatedBefore=2012-11-01&createdBy=123&name=GOTV&$expand=canvassers
A paginated list of MiniVAN Export objects.
Use this endpoint to get full details for a MiniVAN Export
The request has no parameters
GET /minivanExports/888777
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.
The following is an example of a Note Category:
{
"assignableTypes": [
"Event",
"Organization"
],
"noteCategoryId": 23,
"name": "Venue Directions"
}
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 |
Use this endpoint to retrieve all available Note Category Types.
In almost all cases, the available types are:
Event
Location
Person
Organization
This endpoint takes no parameters.
GET /notes/categoryTypes
This endpoint returns an array of strings.
[
"Person",
"Organization",
"Event",
"Location"
]
Use this endpoint to retrieve all available Note Categories.
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.
This endpoint takes no parameters.
GET /notes/noteCategories
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"
}
]
Use this endpoint to retrieve a specific Note Category.
Parameter | Location | Type | Description |
---|---|---|---|
noteCategoryId |
route | int | Required; Unique identifier of an existing Note Category |
GET /notes/noteCategories/24
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
.
This Online Actions Forms endpoint allows you to pull metadata about your online forms.
{
"formTrackingId": "j_STKe8rYxkEVvg2",
"formName": "My Event Form",
"formType": "EventSignupForm",
"formTypeId": 11,
"dateCreated": "2019-12-09T00:09:00Z",
"createdByEmail": "invalid@fake.ngpvan.com",
"dateModified": "2019-12-11T03:47:00Z",
"modifiedByEmail": "invalid@fake.ngpvan.com",
"isActive": true,
"designation": {
"designationId": 123456789,
"name": "Jane for Congress Committee"
},
"confirmationEmailData": {
"fromEmail": "jim@gotham.ci.us",
"fromName": "Jim",
"fromSubject": "Thank you for signing up",
"replyToEmail": "jim@gotham.ci.us",
"copyToEmails": [
"jim@gotham.ci.us",
"jim.gordon@batmail.com",
"knope@citycouncil.pawnee.in.example.org"
],
"isConfirmationEmailEnabled": true,
"isRecurringEmailEnabled": true
},
"activistCodes": [
1234567,
4567890,
1230789,
1472583
],
"eventId": 123456,
"codeId": null,
"campaignId": 7777,
"isConfirmedOptInEnabled": false
}
Property | Type | Description |
---|---|---|
formTrackingId |
string | Unique identifer for specific forms |
formName |
string | The Display Name for the form |
formType |
string | The name for the form type |
formTypeId |
int | The ID for the form type |
dateCreated |
date | The date the form was created |
createdByEmail |
string | The email address of the user who created the form |
dateModified |
date? | The date the form was last modified, may return null |
modifiedByEmail |
string | The email address of the user who last modified the form, may return null |
isActive |
bool | If the form is active or not |
designation |
object | A designation object if the form accepts payments |
confirmationEmailData |
object | An object containing confirmation email data |
eventId |
int? | The ID for an event, if there is an event associated with the form. Otherwise it returns null. |
codeId |
int? | The ID of the code, if one is attached to the form. Otherwise it returns null. |
activistCodes |
array | An array of Activist Code IDs. May return null |
campaignId |
int? | The ID of a campaign if one is applied otherwise it returns null |
isConfirmedOptInEnabled |
bool? | If Confirmed Opt In is enabled or not |
All Confirmation Email Data is optional. If confirmation email information was added to the form that data will be returned.
Property | Type | Description |
---|---|---|
fromEmail |
string | The email address where the confirmation email comes from. Otherwise it returns null. |
fromName |
string | The name of the person the confirmation email comes from. Otherwise it returns null. |
fromSubject |
string | The subject the confirmation email was sent with. Otherwise it returns null. |
replyToEmail |
string | The ‘reply to’ email address for the confirmation email. Otherwise it returns null. |
copyToEmails |
array | An array of ‘copy to’ email addresses |
isConfirmationEmailEnabled |
bool | A flag for if the confirmation email is enabled |
isRecurringEmailEnabled |
bool | A flag for if recurring email is enabled |
Use this endpoint to retrieve all Online Action Forms that are available in the current context.
This endpoint accepts standard pagination parameters and returns a standard paginated response.
By default, this endpoint returns 200 records per request. A maximum of 200 records per request is allowed via the $top
parameter.
GET /onlineActionsForms?$top=10&$skip=20
This endpoint responds with a standard paged response of Online Actions Forms ordered by dateModified
(or dateCreated if the form has not been modified.)
{
"items": [
{
"formTrackingId": "j_STKe8rYxkEVvg2",
"formName": "My Event Form",
"formType": "EventSignupForm",
"formTypeId": 11,
"dateCreated": "2019-12-09T00:09:00Z",
"createdByEmail": "invalid@fake.ngpvan.com",
"dateModified": "2019-12-11T03:47:00Z",
"modifiedByEmail": "invalid@fake.ngpvan.com",
"isActive": true,
"designation": {
"designationId": 123456789,
"name": "Jane for Congress Committee"
},
"confirmationEmailData": {
"fromEmail": "jim@gotham.ci.us",
"fromName": "Jim",
"fromSubject": "Thank you for signing up",
"replyToEmail": "jim@gotham.ci.us",
"copyToEmails": [
"jim@gotham.ci.us",
"jim.gordon@batmail.com",
"knope@citycouncil.pawnee.in.example.org"
],
"isConfirmationEmailEnabled": true,
"isRecurringEmailEnabled": true
},
"activistCodes": [
1234567,
4567890,
1230789,
1472583
],
"eventId": 123456,
"codeId": null,
"campaignId": 7777,
"isConfirmedOptInEnabled": false
},
{
"formTrackingId": "oVy1gfQW4MusasRhZojv8A2",
"formName": "Fundraiser 2",
"formType": "EventSignupForm",
"formTypeId": 11,
"dateCreated": "2019-12-09T00:09:00Z",
"createdByEmail": "invalid@fake.ngpvan.com",
"dateModified": "2019-12-11T03:47:00Z",
"modifiedByEmail": "invalid@fake.ngpvan.com",
"isActive": true,
"designation": {
"designationId": 123456789,
"name": "Jane for Congress Committee"
},
"confirmationEmailData": {
"fromEmail": "jim@gotham.ci.us",
"fromName": "Jim",
"fromSubject": "Thank you for signing up",
"replyToEmail": "jim@gotham.ci.us",
"copyToEmails": [
"jim@gotham.ci.us",
"jim.gordon@batmail.com",
"knope@citycouncil.pawnee.in.example.org"
],
"isConfirmationEmailEnabled": true,
"isRecurringEmailEnabled": true
},
"activistCodes": [
1234567
],
"eventId": 123456,
"codeId": null,
"campaignId": 7777,
"isConfirmedOptInEnabled": false
}
],
"nextPageLink": null,
"count": 2
}
Use this endpoint to retrieve information about a specific Online Actions Form available in the current context.
This endpoint accepts standard list parameters, returns a standard Online Actions Form object, and takes the following filter parameters:
Parameter | Location | Type | Description |
---|---|---|---|
formTrackingId |
route | string | Unique identifier for a specific form. |
GET /onlineActionsForms/TdcRQrFOH3zqmWjy9vA2
A standard Online Actions Form object, if found.
“Is a Cell?” statuses indicate the different confidence levels for whether a phone number is a cell phone. Having these values allow engaging with the right contacts using the right engagement channel at the right time e.g. to identify supporters who have phones that can receive SMS.
Use this endpoint to retrieve all available “Is a Cell?” statuses which can be assigned to a phone number.
Auto-assignment of this value occurs when an explicit status has not been provided for a phone number, in which case phone numbers are checked against a cell matching data source, which verifies if a number is a likely or verified cell phone number.
Note: Auto-assigned values can be overridden by explicitly provided values.
GET /phones/isCellStatuses
{
"items": [
{
"statusId": 1,
"statusName": "Verified Cell"
},
{
"statusId": 2,
"statusName": "Likely Cell"
},
{
"statusId": 3,
"statusName": "Likely Not a Cell"
},
{
"statusId": 4,
"statusName": "Not a Cell"
}
],
"nextPageLink": null,
"count": 4
}
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 after 30 days.
The following is an example of a Printed List:
{
"number": "15981815-49117",
"name": "Test Turf 01"
}
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 |
Use this endpoint to retrieve all available Printed Lists
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.
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 |
GET /printedLists?generatedAfter=2012-10-01&generatedBefore=2012-11-01&createdBy=123&folderName=GOTV&turfName=Precinct+1
A paginated list of Printed List objects.
Use this endpoint to get full details for a printed list
The request has no parameters
GET /printedLists/16531169-91333
A Relationship is a category which describes how two people know each other. Relationships may be used to describe family, social, and work connections, among others. These services indicate the relationship options which are available for use within the current context.
A paginated list of options for relationships in the current context.
{
"items": [
{
"id": 34,
"name": "Acquaintance"
},
{
"id": 141,
"name": "Affiliate"
},
{
"id": 101,
"name": "Aide"
}
],
"count": 20,
"nextPageLink": "https://api.securevan.com/v4/relationships?$top=3&$skip=4"
}
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, language preference, sexual orientation, and gender. These services indicate the demographic options which are available for use in describing a person within the current context.
Use this endpoint to retrieve all Reported Races that are available in the current context.
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
}
Use this endpoint to retrieve all Reported Ethnicities that are available in the current context.
This endpoint accepts standard pagination parameters.
GET /reportedEthnicities?$top=3&$skip=1
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
}
Use this endpoint to retrieve all Reported Language Preferences that are available in the current context.
This endpoint accepts standard pagination parameters.
GET /reportedLanguagePreferences?$top=3&$skip=1
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
}
Use this endpoint to retrieve all Reported Sexual Orientations that are available in the current context.
This endpoint accepts standard pagination parameters.
GET /reportedSexualOrientations?$top=3&$skip=1
A paginated list of options for reporting sexual orientation in the current context.
{
"items": [
{
"reportedSexualOrientationId": 2,
"reportedSexualOrientationName": "Androsexual"
},
{
"reportedSexualOrientationId": 3,
"reportedSexualOrientationName": "Asexual"
},
{
"reportedSexualOrientationId": 4,
"reportedSexualOrientationName": "Autosexual"
}
],
"nextPageLink": "https://api.securevan.com/v4/reportedSexualOrientations?$top=3&$skip=4",
"count": 22
}
Use this endpoint to retrieve all Reported Genders that are available in the current context.
A paginated list of options for reporting gender in the current context.
{
"items": [
{
"reportedGenderId": 19,
"reportedGenderName": "Androgyne"
},
{
"reportedGenderId": 1,
"reportedGenderName": "Androgynous"
},
{
"reportedGenderId": 20,
"reportedGenderName": "Bigender"
}
],
"nextPageLink": "https://api.securevan.com/v4/reportedGenders?$top=3&$skip=4",
"count": 49
}
Use this endpoint to retrieve all Pronouns that are available in the current context.
A paginated list of options for reporting sexual orientation in the current context.
{
"items": [
{
"preferredPronounId": 6,
"preferredPronounName": "E/Em/Eirs"
},
{
"preferredPronounId": 7,
"preferredPronounName": "Ey/Em/Eirs"
},
{
"preferredPronounId": 2,
"preferredPronounName": "He/Him/His"
}
],
"nextPageLink": "https://api.securevan.com/v4/pronouns?$top=3&$skip=4",
"count": 14
}
A Saved List is a fixed set of People records. Saved Lists are contained within Folders. A Saved List is available via the API only if the Saved List is contained in a Folder which is shared with the API key, and which was created in the API key’s committee.
The following is an example of a Saved List:
{
"savedListId": 999888777,
"name": "GOTV list",
"description": "People we want to talk to for GOTV",
"listCount": 2000,
"doorCount": 987
}
Each Saved List has the following properties:
Property | Type | Description |
---|---|---|
savedListId |
int | Unique identifier for a Saved List |
name |
string | The name given to the list when it was created |
description |
string | The description given to the list when it was created |
listCount |
int | The number of People in the list |
doorCount |
int | The number of doors in the list; may be less than listCount if, for example, some of the People in the list live in the same household. |
Use this endpoint to retrieve metadata about available Saved Lists. The list of people in a Saved List is not available via this endpoint.
This endpoint accepts standard pagination parameters and returns a standard paginated response.
The endpoint takes the following optional filter parameters:
Parameter | Location | Type | Description |
---|---|---|---|
folderId |
query | int | If indicated, retrieve only Saved Lists from this Folder. |
maxDoorCount |
query | int | If indicated, retrieve only Saved Lists containing this number of doors or fewer. |
maxPeopleCount |
query | int | If indicated, retrieve only Saved Lists containing this number of People or fewer. |
GET /savedLists?folderId=1234&maxDoorCount=1000&maxPeopleCount=2000
A paginated list of Saved List objects.
Use this endpoint to get metadata about a saved list.
The request has no parameters
GET /savedLists/999888777
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 all available Score Updates, optionally filtered by search parameters.
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
{
"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
}
Retrieve a single score update
Parameter | Location | Type | Description |
---|---|---|---|
scoreUpdateId |
route | int | Required; Unique identifier of the score update to be retrieved |
GET /scoreUpdates/1888
{
"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"
}
Changes the status of a score (e.g., from PendingApproval
to Approved
). Score updates that are approved, are applied at off-peak hours.
Parameter | Location | Type | Description |
---|---|---|---|
scoreUpdateId |
route | int | Required; Unique identifier of the score update to be changed |
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
, Disapproved
→ Canceled
PendingApproval
, Disapproved
→ Approved
PendingApproval
, Approved
→ Disapproved
Approved
, Disapproved
→ PendingApproval
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"
}
204 No Content
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 all available range scores
GET /scores
{
"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
}
Retrieve a single range score
Parameter | Location | Type | Description |
---|---|---|---|
scoreId |
route | int | Required; Unique identifier of the score to be retrieved |
GET /scores/123
{
"scoreId": 123,
"name": "Haberdashery score",
"shortName": "HATS",
"description": "Likelihood of owning a hat",
"minValue": 1.00,
"maxValue": 10.00
}
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
)event
)shift
)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.
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.
{
"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"
}
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 |
supporterGroupId |
int | Optional; a Supporter Group to associate with this Event Signup |
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 |
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 |
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 |
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 |
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 |
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 |
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.
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
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"
}
]
Use this endpoint to retrieve a specific Event Signup.
Parameter | Location | Type | Description |
---|---|---|---|
eventSignupId |
route | int | Required; Unique identifier of an existing event shift |
GET /signups/2452
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
.
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.
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. |
Either the eventId
parameter, or the vanId
parameter, must be specified.
GET /signups?vanId=100476252
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",
},
{
"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",
}
],
"nextPageLink": null,
"count": 2
}
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., Scheduled → Canvassed ). Consult the VAN UI for a detailed mapping.
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
}
}
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.
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., Scheduled → Canvassed ). Consult the VAN UI for a detailed mapping.
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
}
}
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.
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.
Parameter | Location | Type | Description |
---|---|---|---|
eventSignupId |
route | int | Required; Unique identifier of an existing Signup |
DELETE /signups/2423
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.
Stories allow users to collect, track, and departmentally assign personal stories from supporters that highlight the work or impact of an organization.
{
"storyId": 123,
"title": "Jane Eyre",
"storyText": "There was no possibility of taking a walk that day.",
"storyStatus": {
"storyStatusId": 1,
"statusName": "Submitted"
},
"vanId": 1000000000,
"tags": [
{
"codeId": 123,
"codeName": "Book"
}
],
"campaignId": 123456
}
Each Story has the following properties:
Property | Type | Description |
---|---|---|
storyId |
int | Unique identifier for a Story in this context |
title |
string | The title of the story. |
storyText |
string | The story content. |
storyStatus |
StoryStatus | The status of the story. |
vanId |
int | The MyCampaignID of the MyCampaign contact record the story belongs to |
tags |
array | Optional; an array of zero or more Tags to apply to the Story. |
campaignId |
int | Optional; unique identifier for a Campaign associated with the story in the system |
Each Story Status has the following properties:
Property | Type | Description |
---|---|---|
storyStatusId |
int | Unique identifier for the status of a Story |
statusName |
string | A name given to the status |
Use this endpoint to retrieve the details of a specific Story.
Parameter | Location | Type | Description |
---|---|---|---|
storyId |
route | int | Required; unique identifier of the story to be retrieved |
GET /stories/123
{
"storyId": 123,
"title": "Jane Eyre",
"storyText": "There was no possibility of taking a walk that day.",
"storyStatus": {
"storyStatusId": 1,
"statusName": "Submitted"
},
"vanId": 1000000000,
"tags": [
{
"codeId": 123,
"codeName": "Book"
}
],
"campaignId": 123456
}
Returns a standard Story object, if found.
If the specified Story does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
Use this endpoint to create a new Story.
Accepts a standard Story object, simple types and no read-only values specified.
POST /stories
{
"title": "A Tale of Two Cities",
"storyText": "It was the best of times, it was the worst of times ...",
"storyStatus": {
"storyStatusId": 1
},
"vanId": 1000000000,
"tags": [
{
"codeId": 123
},
{
"codeId": 456
}
],
"campaignId": 123456
}
If successful, the endpoint responds with HTTP Status Code 201 Created
. The response body will contain a Story object populated with the new Story’s integer StoryId.
Responses to invalid requests follow the standard for input validation responses.
Supporter Groups enable volunteer coordinators and organizers to more easily manage, schedule, and report on the activity that groups of people do on behalf of their organization. Examples of these may include alumni associations, religious groups, neighborhood teams, or company volunteer corps that volunteer with the organization. Supporter Groups are only available in My Campaign.
The following is an example of a Supporter Group:
{
"id": 15,
"name": "North End Volunteers",
"description": "Volunteers from the North End that help out frequently"
}
Each Supporter Group has the following properties:
Property | Type | Description |
---|---|---|
id |
int | Read-only; Unique identifier for a Supporter Group |
name |
string | Required; A name for this Supporter Group, no longer than 100 characters |
description |
string | Optional; A description for this Supporter Group, no longer than 200 characters |
Use this endpoint to retrieve all available supporter groups
This endpoint accepts standard pagination parameters and returns a standard paginated response.
A paginated list of Supporter Group objects.
Use this endpoint to create a new supporter group
This endpoint accepts a standard Supporter Group object with no read-only values specified.
If successful, the endpoint responds with HTTP Status Code 201 Created
and the integer id of the created Supporter Group in the response body.
Use this endpoint to delete a supporter group. Deleting a supporter group will also remove every member from it.
The request has no parameters
DELETE /supporterGroups/1234
If successful, the endpoint responds with HTTP Status Code 204 No Content
.
Use this endpoint to retrieve a supporter group
The request has no parameters
GET /supporterGroups/1234
Use this endpoint to add a person to a supporter group
The request has no parameters
PUT /supporterGroups/1234/people/5678
If successful, the endpoint responds with HTTP Status Code 204 No Content
.
Use this endpoint to remove a person from a supporter group
The request has no parameters
DELETE /supporterGroups/1234/people/5678
If successful, the endpoint responds with HTTP Status Code 204 No Content
and the integer id of the created Supporter Group in the response body.
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.
{
"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 |
Use this endpoint to retrieve all Survey Questions that are available in the current context.
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
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
}
Use this endpoint to retrieve information about a specific Survey Question (and its set of Survey Responses) available in the current context.
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
A standard Survey Question object, if found.
A Target Export Job is a long-running, asynchronous process for looking up a specific Target and retrieving the list of VANIDs and their associated target subgroups in CSV format.
Use this endpoint to request a new Target Export Job for a specified Target.
{
"targetId": "2",
"webhookUrl": "https://webhook.example.org/completedExportJobs"
}
Property | Type | Description |
---|---|---|
targetId |
date | Required; unique identifier for a specific Target. |
webhookUrl |
string | Optional; the URL to be notified when the Target Export Job has completed. |
If successful, the endpoint responds with HTTP Status Code 201 Created
and the integer ID of the created Target Export Job in the response body.
{
"exportJobId": 123456
}
Use this endpoint to retrieve information about the status of a specific Target Export Job available in the current context.
This endpoint takes the following parameter:
Parameter | Location | Type | Description |
---|---|---|---|
exportJobId |
route | int | Unique identifier for a specific Target Export Job. |
GET /targetExportJobs/1234
A standard Target Export Job Result object, if found.
{
"targetId": 55,
"file": {
"downloadUrl": "https://www.example.com/some-unique-file-name.csv",
"dateExpired": "2020-04-07T09:45:51.4954493-04:00",
"recordCount": 16
},
"webhookUrl": "https://webhook.example.org/completedExportJobs",
"exportJobId": 1234,
"jobStatus": "Complete"
}
Each Target Export Job Result has the following properties:
Property | Type | Description |
---|---|---|
targetid |
int | Unique identifier for the requested Target. |
file |
object | Information about the file containing the exported Target data. |
webhookUrl |
string | The URL to be notified when the Target Export Job has completed. |
exportJobId |
int | The unique identifier for the requested Target Export Job. |
jobStatus |
string | Can be one of Pending , InProcess , Error , or Complete . |
Each File has the following properties:
Property | Type | Description |
---|---|---|
downloadUrl |
string | The URL where the completed Target Export Job can be downloaded; will be null unless jobStatus is Complete . |
dateExpired |
date | The date the download URL expires. |
recordCount |
int | The number of records contained in the export file. |
Targets are built around Saved Lists and Saved Searches, or Subgroups, that are run on a nightly basis. Targets can be shared with committees, and are generally limited to managing extremely large lists affecting more than one committee or statewide campaigns.
The following is an example of a Target:
{
"targetId": 33,
"name": "GOTV Targets",
"type": "Dynamic",
"description": null,
"points": 5,
"areSubgroupsSticky": false,
"status": "Ready",
"subgroups": [
{
"fullName": "Excellent Voters",
"name": "Excellent",
"subgroupId": 123,
"isAssociatedWithBadges": false
},
{
"fullName": "Warm Voters",
"name": "Warm",
"subgroupId": 456,
"isAssociatedWithBadges": false
}
]
}
Each Target has the following properties:
Property | Type | Description |
---|---|---|
targetId |
int | Unique identifier for a Target. |
name |
string | The name given to the Target when it was created. |
type |
string | Can be Static or Dynamic . Static Targets are based on Saved Lists and Dynamic Targets are based on Saved Searches. |
description |
string | The description given to the Target when it was created. |
points |
int | The number of points used by a Target. |
areSubgroupsSticky |
bool | Indicates that any contact that meets the criteria of a Subgroup will remain in that Subgroup and not be reassigned based on new data. |
status |
string | Can be one of Setup , Ready , or Active . Setup means the Target is in the configuration process. Ready indicates that the Target is ready to be run in the nightly update. Active indicates that the Target has completed at least one nightly run. |
subgroups |
array | An array of Subgroup objects. |
Each Subgroup has the following properties:
Property | Type | Description |
---|---|---|
fullName |
int | The long name for the Subgroup. |
name |
string | The medium name for the Subgroup. |
subgroupId |
int | Unique identifier for a Subgroup. |
isAssociatedWithBadges |
bool | Indicates whether the Subgroup name is displayed on the contact record in the UI. |
Use this endpoint to retrieve all Targets that are available in the current context.
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: subgroups
.
The endpoint takes the following optional filter parameters:
Parameter | Location | Type | Description |
---|---|---|---|
status |
query | string | Optional; can be one of Setup , Ready , or Active . |
type |
query | string | Optional; can be one of Static or Dynamic . |
GET /targets?status=Active&$expand=subgroups
This endpoint responds with a standard paged response of Targets.
{
"items": [
{
"targetId": 33,
"name": "GOTV Targets",
"type": "Dynamic",
"description": null,
"points": 5,
"areSubgroupsSticky": false,
"status": "Active",
"subgroups": [
{
"fullName": "Excellent Voters",
"name": "Excellent",
"subgroupId": 123,
"isAssociatedWithBadges": false
},
{
"fullName": "Warm Voters",
"name": "Warm",
"subgroupId": 456,
"isAssociatedWithBadges": false
}
]
},
{
"targetId": 55,
"name": "Latinx Voters",
"type": "Dynamic",
"description": null,
"points": 7,
"areSubgroupsSticky": false,
"status": "Active",
"subgroups": [
{
"fullName": "Senior Voters",
"name": "Seniors",
"subgroupId": 125,
"isAssociatedWithBadges": false
},
{
"fullName": "55 and Under",
"name": "Under 55",
"subgroupId": 346,
"isAssociatedWithBadges": false
}
]
}
],
"nextPageLink": null,
"count": 2
}
Use this endpoint to retrieve information about a specific Target (and its Subgroups) available in the current context.
This endpoint takes the following parameter:
Parameter | Location | Type | Description |
---|---|---|---|
targetId |
route | int | Required; unique identifier for a specific Target. |
GET /targets/1234
A standard Target object, if found.
If the specified Target does not exist, this endpoint will return an error with HTTP Status Code 404 Not Found
.
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:
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”.
Use this endpoint to retrieve all District Field Values assigned to a user
This endpoint takes no parameters.
GET /users/1234/districtFieldValues
This endpoint returns a standard User District Field Value Assignment.
{
"districtFieldValues": [
"W1P2",
"W1P3",
"W2P1"
]
}
Use this endpoint to assign additional district field values to a user.
The request is a standard User District Field Value Assignment.
POST /users/12345/districtFieldValues
{
"districtFieldValues": [
"W1P2",
"W1P3",
"W2P1"
]
}
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"
]
}
Use this endpoint to completely overwrite the district field values assignments for a user.
The request is a standard User District Field Value Assignment.
PUT /users/12345/districtFieldValues
{
"districtFieldValues": [
"W1P2",
"W4P1"
]
}
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"
]
}
A Voter Registration Batch is a way to package registration records and apply helpful tracking and metadata as part of the processing of comparing and adding records from the Voter Registration database to the My Voters database. A VR Batch must be state specific and can only include records entered from the same form.
The following is an overview of the Voter Registration Batch.
{
"voterRegistrationBatchId": 100,
"name": "VR Batch",
"description": "VR Batch Description",
"stateCode": "MA",
"form": {
"formId": 101,
"name": "VR Form"
},
"status": "Entering",
"programType": {
"programTypeId": 201,
"name": "VR Program"
},
"personType": "Applicant",
"dateCreated": "2019-08-01T00:00:00Z"
}
The following is an overview of the Voter Registration Batch object and its related objects.
Property | Type | Description |
---|---|---|
voterRegistrationBatchId |
int | Read-only; Unique identifier for a VR Batch in this context. |
name |
string | Required. Full display name of the batch. |
description |
string | Description of the batch. |
stateCode |
string | Required. The US state of the batch. Must be a valid two letter US state abbreviation. |
form |
object | Required. The voter registration form to associate with this batch. |
status |
string | A string representing the status of the batch. See below for valid values of Batch Status. |
programType |
object | The “Program” for this batch. |
personType |
string | A string representing the type of persons to be added to this batch. See below for valid values of Person Type. |
dateCreated |
date | The date created of the batch. |
Property | Type | Description |
---|---|---|
formId |
int | Read-only; Unique identifier for a Voter Registration Form in this context. |
name |
string | The name of this form. |
Property | Type | Description |
---|---|---|
programTypeId |
int | Read-only; Unique identifier for a Program Type in this context. |
name |
string | The name of this program type. |
One of
Unknown
Entering
Completed
Committed
Processed
One of
Applicants
Pledges
Search for voter registration batches, with required filtering.
This endpoint accepts standard pagination parameters and returns a standard paginated response.
Unless designated as optional, the endpoint requires at least one following filter parameters:
Parameter | Location | Type | Description |
---|---|---|---|
createdBefore |
query | date | Filters batches created before a given date (in the format yyyy-MM-dd ) |
createdAfter |
query | date | Filters batches created after a given date (in the format yyyy-MM-dd ) |
status |
query | string | Filters batches by batch status. |
stateCode |
query | string | Filters batches by state. Must be a valid two letter US state abbreviation. |
onlyMyBatches |
query | bool | Filters batches created by the API key. |
programType |
query | object | Filters batches by program type. |
personType |
query | string | Filters batches by person type. |
$orderby |
query | string | Optional; sorts results in ascending (asc ) or descending (desc ) order by a comma delimited list of properties: DateCreated , StateCode , Name . Note that a space is required between the property and asc or desc . |
GET /voterRegistrationBatches?StateCode=MA&$orderby=DateCreated desc&$top=1
This endpoint responds with a standard paged response of Voter Registration Batches.
{
"items": [
{
"voterRegistrationBatchId": 100,
"name": "VR Batch",
"description": "VR Batch Description",
"stateCode": "MA",
"form": {
"formId": 101,
"name": "VR Form"
},
"status": "Entering",
"programType": {
"programTypeId": 201,
"name": "VR Program"
},
"personType": "Applicant",
"dateCreated": "2019-08-01T00:00:00Z"
}
],
"nextPageLink": "https://api.securevan.com/v4/voterRegistrationBatches?StateCode=MA&$orderby=DateCreated desc&$top=1&$skip=1",
"count": 25
}
Returns a list of registration programs available for use when creating a new voter registration batch via POST /voterRegistrationBatches or filtering for batches via GET voterRegistrationBatches.
GET /voterRegistrationBatches/programTypes
{
"items": [
{
"programTypeId": 201,
"name": "VR Program"
},
{
"programTypeId": 202,
"name": "VR Program 2"
},
{
"programTypeId": 203,
"name": "VR Program 3"
}
],
"nextPageLink": null,
"count": 3
}
Returns a list of registration forms available for use when creating a new voter registration batch via POST /voterRegistrationBatches.
GET /voterRegistrationBatches/registrationForms
{
"items": [
{
"formId": 101,
"name": "VR Form"
}
],
"nextPageLink": null,
"count": 1
}
Retrieve list of fields available for use when sending registrants via POST /voterRegistrationBatches/{batchId}/people. Though the fields themselves are not currently state-specific, the possible values for dropdown fields are state-specific.
State must be a valid US state abbreviation.
GET /voterRegistrationBatches/states/MA/supportedFields
{
"items": [
{
"customPropertyKey": "VR:CatBreed",
"displayName": "Cat Breed",
"fieldType": "Dropdown",
"maxFieldLength": null,
"possibleValues": [
{
"key": "A",
"value": "American Shorthair"
},
{
"key": "B",
"value": "Bengal"
},
{
"key": "M",
"value": "Maine Coon"
},
{
"key": "P",
"value": "Persian"
}
{
"key": "U",
"value": "Unknown"
}
]
},
{
"customPropertyKey": "VR:DateAcquiredCat",
"displayName": "Date Acquired Cat",
"fieldType": "Date",
"maxFieldLength": null,
"possibleValues": null
},
{
"customPropertyKey": "VR:HasCat",
"displayName": "Has Cat",
"fieldType": "Checkbox",
"maxFieldLength": null,
"possibleValues": null
},
{
"customPropertyKey": "VR:CatName",
"displayName": "Cat Name",
"fieldType": "Text",
"maxFieldLength": 50,
"possibleValues": null
}
],
"nextPageLink": null,
"count": 4
}
Create a new Voter Registration Batch.
POST /voterRegistrationBatches
{
"name": "VR Batch",
"description": "VR Batch Description",
"stateCode": "MA",
"programType": {
"programTypeId": 201
},
"form": {
"formId": 101
},
"personType": "Applicant"
}
If successful, the endpoint responds with HTTP Status Code 201 Created
and an object containing the new Voter Registration Batch’s Id.
Update the status of a voter registration batch.
The current status of the specified batch dictates which batch status values are valid. When a new batch is created via POST /voterRegistrationBatches, it is set to the default status of Entering. From Entering, a batch can only change to Completed. Then, from Completed, a batch can either be changed back to Entering or to Committed. Once a batch is committed, it cannot be changed to any other status. No other status values are accepted.
Changing a status to Committed processes the batch and makes registrants available for searching in the VAN interface.
PATCH /voterRegistrationBatches/100
{
status: "Completed"
}
If successful, the endpoint responds with HTTP Status Code 204 No Content
and an empty response body.
Use this endpoint to submit up to 25 registrants to a Voter Registration Batch. Fields published via POST /voterRegistrationBatches should be specified in CustomProperties.
Property | Type | Description |
---|---|---|
alternateId |
string | A Unique Identifier, for your reference only. Value is not stored in the database. |
person |
object | Required; A People object which describes the registrant. |
customProperties |
object | An array of Supported Fields objects. |
POST /voterRegistrationBatches/100/people
[
{
alternateId: "fd351cfa-4790-4f91-9665-63899f965217",
person: {
"firstName": "Jane",
"lastName": "Doe",
},
customProperties: [
{
key: "VR:HasCat",
value: "true"
},
{
key: "VR:CatName",
value: "Humphrey"
}
]
},
{
alternateId: "807883fc-0103-4edf-814c-3eea9602290f",
person: {
"firstName": "John",
"lastName": "Smith",
},
customProperties: [
{
key: "VR:HasCat",
value: "X"
}
]
}
]
Property | Type | Description |
---|---|---|
alternateId |
string | A Unique Identifier, for your reference only. Value is not stored in the database. |
vanId |
string | If result is Success , the vanId of the registrant’s record. |
result |
string | Success or Failure |
errors |
object | If result is Failure , an array of Errors objects. |
[
{
"alternateId": "ab694282-1d74-474b-90dc-173aa73f44b1",
"vanId": "10000000",
"result": "Success",
"errors": null
},
{
"alternateId": "807883fc-0103-4edf-814c-3eea9602290f",
"vanId": null,
"result": "Failure",
"errors": [
{
"code": "INVALID_PARAMETER",
"text": "'VR:HasCat' value 'X' is invalid",
"properties": [
"value"
]
}
]
}
]