New .NET Library for Accessing the Survey Monkey API
- by Ben Emmett
I’ve used Survey Monkey’s API for a while, and though it’s pretty powerful, there’s a lot of boilerplate each time it’s used in a new project, and the json it returns needs a bunch of processing to be able to use the raw information. So I’ve finally got around to releasing a .NET library you can use to consume the API more easily.
The main advantages are:
Only ever deal with strongly-typed .NET objects, making everything much more robust and a lot faster to get going
Automatically handles things like rate-limiting and paging through results
Uses combinations of endpoints to get all relevant data for you, and processes raw response data to map responses to questions
To start, either install it using NuGet with PM> Install-Package SurveyMonkeyApi (easier option), or grab the source from https://github.com/bcemmett/SurveyMonkeyApi if you prefer to build it yourself. You’ll also need to have signed up for a developer account with Survey Monkey, and have both your API key and an OAuth token.
A simple usage would be something like:
string apiKey = "KEY";
string token = "TOKEN";
var sm = new SurveyMonkeyApi(apiKey, token);
List<Survey> surveys = sm.GetSurveyList();
The surveys object is now a list of surveys with all the information available from the /surveys/get_survey_list API endpoint, including the title, id, date it was created and last modified, language, number of questions / responses, and relevant urls. If there are more than 1000 surveys in your account, the library pages through the results for you, making multiple requests to get a complete list of surveys.
All the filtering available in the API can be controlled using .NET objects. For example you might only want surveys created in the last year and containing “pineapple” in the title:
var settings = new GetSurveyListSettings
{
Title = "pineapple",
StartDate = DateTime.Now.AddYears(-1)
};
List<Survey> surveys = sm.GetSurveyList(settings);
By default, whenever optional fields can be requested with a response, they will all be fetched for you. You can change this behaviour if for some reason you explicitly don’t want the information, using
var settings = new GetSurveyListSettings
{
OptionalData = new GetSurveyListSettingsOptionalData
{
DateCreated = false,
AnalysisUrl = false
}
};
Survey Monkey’s 7 read-only endpoints are supported, and the other 4 which make modifications to data might be supported in the future. The endpoints are:
Endpoint
Method
Object returned
/surveys/get_survey_list
GetSurveyList()
List<Survey>
/surveys/get_survey_details
GetSurveyDetails()
Survey
/surveys/get_collector_list
GetCollectorList()
List<Collector>
/surveys/get_respondent_list
GetRespondentList()
List<Respondent>
/surveys/get_responses
GetResponses()
List<Response>
/surveys/get_response_counts
GetResponseCounts()
Collector
/user/get_user_details
GetUserDetails()
UserDetails
/batch/create_flow
Not supported
Not supported
/batch/send_flow
Not supported
Not supported
/templates/get_template_list
Not supported
Not supported
/collectors/create_collector
Not supported
Not supported
The hierarchy of objects the library can return is
Survey
List<Page>
List<Question>
QuestionType
List<Answer>
List<Item>
List<Collector>
List<Response>
Respondent
List<ResponseQuestion>
List<ResponseAnswer>
Each of these classes has properties which map directly to the names of properties returned by the API itself (though using PascalCasing which is more natural for .NET, rather than the snake_casing used by SurveyMonkey).
For most users, Survey Monkey imposes a rate limit of 2 requests per second, so by default the library leaves at least 500ms between requests. You can request higher limits from them, so if you want to change the delay between requests just use a different constructor:
var sm = new SurveyMonkeyApi(apiKey, token, 200); //200ms delay = 5 reqs per sec
There’s a separate cap of 1000 requests per day for each API key, which the library doesn’t currently enforce, so if you think you’ll be in danger of exceeding that you’ll need to handle it yourself for now. To help, you can see how many requests the current instance of the SurveyMonkeyApi object has made by reading its RequestsMade property.
If the library encounters any errors, including communicating with the API, it will throw a SurveyMonkeyException, so be sure to handle that sensibly any time you use it to make calls.
Finally, if you have a survey (or list of surveys) obtained using GetSurveyList(), the library can automatically fill in all available information using
sm.FillMissingSurveyInformation(surveys);
For each survey in the list, it uses the other endpoints to fill in the missing information about the survey’s question structure, respondents, and responses. This results in at least 5 API calls being made per survey, so be careful before passing it a large list.
It also joins up the raw response information to the survey’s question structure, so that for each question in a respondent’s set of replies, you can access a ProcessedAnswer object. For example, a response to a dropdown question (from the /surveys/get_responses endpoint) might be represented in json as
{
"answers": [
{
"row": "9384627365",
}
],
"question_id": "615487516"
}
Separately, the question’s structure (from the /surveys/get_survey_details endpoint) might have several possible answers, one of which might look like
{
"text": "Fourth item in dropdown list",
"visible": true,
"position": 4,
"type": "row",
"answer_id": "9384627365"
}
The library understands how this mapping works, and uses that to give you the following ProcessedAnswer object, which first describes the family and type of question, and secondly gives you the respondent’s answers as they relate to the question. Survey Monkey has many different question types, with 11 distinct data structures, each of which are supported by the library.
If you have suggestions or spot any bugs, let me know in the comments, or even better submit a pull request .