NAV Navbar
shell go C#
  • Introduction
  • Welcome
  • SDKs & Client Libraries
  • Authentication
  • Pagination
  • Filtering
  • Sorting
  • Start & End Links
  • Core Resources
  • Projects
  • Line Items
  • Pricing & Feasibility
  • Notifications
  • Events
  • Billing & Invoicing
  • Invoicing
  • Reconciliation
  • Data Endpoints
  • Countries & Languages
  • Attributes
  • Categories
  • Guidelines
  • Survey Content
  • Quota Plan
  • Introduction

    Welcome

    Dynata Sample API, a REST based API, can be programmatically used to connect your market research surveys directly with Dynata panel.

    This API document describes the usage and resources needed for integrating with Dynata Sample API. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. JSON is returned by all API responses, including errors.

    To make the APIs explorable, we provide a Test account. Please send an email to samplify-api@researchnow.com to request for one. Requests sent to the test account does not go to our actual panelists and therefore does not incur any cost.

    SDKs & Client Libraries

    We've made a number of open source libraries available for the API:

    Our team is constantly working to add more SDKs, so stay tuned if an SDK is not already available.

    Authentication

    Example Use of JWT Bearer Token

    curl "https://api.researchnow.com/sample/v1/countries"
      -H "Authorization: Bearer eyJhbGciOaS....lBnqwzv_os2N_CA"
    
    // n/a
    
    // n/a
    

    Dynata Sample API uses JSON Web Tokens / JWTs for authentication. After obtaining the JWT it should be passed in the Authorization header as a Bearer token with each request.

    Obtaining an Access Token

    To obtain an access token use the below endpoint. There is no need to decode the JWT in your client application. You can treat it as an opaque token and subsequently pass it to each API endpoint.

    HTTPS Request

    curl "https://api.researchnow.com/auth/v1/token/password" \
      -X POST \
      -H "Content-Type: application/json" \
      -d '{"clientId": "api-gateway", "password": "PW", "username": "USER"}'
    
    // This initializes the client object.
    // The token is acquired with the first API request and is used with subsequent calls.
    // If a request is made and the token has expired, a new one will be automatically acquired.
    
    client := samplify.NewClient("client_id", "username", "password")
    
    // This initializes the client object.
    // The token is acquired with the first API request and is used with subsequent calls.
    // If a request is made and the token has expired, a new one will be automatically acquired.
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    

    POST /auth/v1/token/password

    Request Parameters

    Parameter Description
    clientId Your app id. Provided to you during account setup
    username user's login name. Provided to you during account setup
    password user's password. Provided to you during account setup

    Response Data

    Example Response

    {
      "accessToken": "eyJhbGciOaS....lBnqwzv_os2N_CA",
      "expiresIn": 3600,
      "refreshExpiresIn": 4320,
      "refreshToken": "eyJhbGciOiJSU...DdwzV0sBSCWYUNg",
      "tokenType": "bearer",
      "notBeforePolicy": 0,
      "sessionState": "9372de83-aabd-4588-87d4-f2ca7ae8d00f"
    }
    

    Example Use

    curl "https://api.researchnow.com/sample/v1/countries"
      -H "Authorization: Bearer eyJhbGciOaS....lBnqwzv_os2N_CA"
    
    Parameter Description
    accessToken Access token that should be passed in API calls
    expiresIn Access token expires in this many seconds
    refreshToken Refresh token that can be used to obtain a new access token before the access token expires
    refreshExpiresIn Refresh token expires in this many seconds

    Refreshing an Access Token

    curl "https://api.researchnow.com/auth/v1/token/refresh" \
      -X POST \
      -H "Content-Type: application/json" \
      -d '{"clientId": "api-gateway", "refreshToken": "REFRESH_TOKEN"}'
    
    err := client.RefreshToken()
    
    bool r = await client.RefreshToken();
    
    

    Example Response

    {
      "accessToken": "eyJhbGciO...LD9uarwcl0SjJ_LA",
      "expiresIn": 3600,
      "refreshExpiresIn": 4320,
      "refreshToken": "eyJhbGciOi...j36A5c7NEB9fYuVPWd-w",
      "tokenType": "bearer",
      "notBeforePolicy": 0,
      "sessionState": "9372de83-aabd-4588-87d4-f2ca7ae8d00f"
    }
    

    Access tokens have a limited lifetime but can be refreshed for a new token before they expire. The response from refreshing a token is the same as the response from obtaining the original access token. The accessToken and refreshToken from the response should replace the current session's accessToken and refreshToken. A typical practice is to periodically refresh the access token as long as the user remains logged in.

    HTTPS Request

    POST /auth/v1/token/refresh

    Logging Out

    curl "https://api.researchnow.com/auth/v1/logout" \
      -X POST \
      -H "Content-Type: application/json" \
      -d '{"clientId": "api-gateway", "refreshToken": "REFRESH_TOKEN", "accessToken": "ACCESS_TOKEN"}'
    
    err := client.Logout()
    
    bool r = await client.Logout();
    

    Access tokens have a limited lifetime, but a good practice is to explicitly expire the token when not using the API any more. You can do so by using the logout endpoint. A successful response from logout will return with 204 No Content.

    HTTPS Request

    POST /auth/v1/logout

    Pagination

    Example Use of pagination

    curl "https://api.researchnow.com/sample/v1/countries"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    option := &samplify.QueryOptions{
      Offset: 10,
      Limit:  5,
    }
    res, err := client.GetCountries(option)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    var option = new QueryOptions(10, 5); //offset=10, limit=5
    try
    {
        var res = await client.GetCountries(option);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response

    {
      "data": [
        ...
      ],
      "meta": {
        "links": {
          "first": "https://api.researchnow.com/sample/v1/countries?offset=0",
          "last": "https://api.researchnow.com/sample/v1/countries?offset=35",
          "next": "https://api.researchnow.com/sample/v1/countries?offset=10",
          "self": "https://api.researchnow.com/sample/v1/countries"
        }
      }
    }
    

    All GET endpoints which return an object list supports offset-based pagination. To get the list of all objects, you need to paginate through the results using the offset value and limit value. The offset parameter controls the starting point within the collection of resource results. For example, if you have a collection of 15 items to be retrieved from a resource and you specify limit=5, you can retrieve the entire set of results in 3 successive requests by varying the offset value: offset=0, offset=5, and offset=10. Note that the first item in the collection is retrieved by setting a zero offset.

    To make it easier to navigate, the API will contruct the links together with all the currently used query parameters. You can therefore simply use the links object to navigate to the first, last, next, self pages.

    Pagination Response

    Parameter Description
    first Link for getting results in the first page
    last Link for getting results in the last page
    next Link for getting results in the next page
    self Current link

    Filtering

    Example Use of filtering

    curl "https://api.researchnow.com/sample/v1/countries?isoCode=US"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    option := &samplify.QueryOptions{
      FilterBy: []*samplify.Filter{
        &samplify.Filter{Field: samplify.QueryFieldIsoCode, Value: "US"},
      },
    }
    res, err := client.GetCountries(option)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    var option = new QueryOptions();
    option.AddFilter("isoCode", "US");
    
    try
    {
        var res = await client.GetCountries(option);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response

    {
      "data": [
        {
          "id": "US",
          "isoCode": "US",
          "countryName": "United States of America",
          "supportedLanguages": [
            {
              "id": "en_US",
              "isoCode": "en_US",
              "languageName": "English (US)"
            },
            {
              "id": "es_US",
              "isoCode": "es_US",
              "languageName": "Spanish (US)"
            }
          ]
        },
        ...
      ]
    }
    

    All GET endpoints which return an object list supports filtering. Filtering can be done by specifying the field name in the query parameters. For the example in the right, filtering can be done for all first level fields: id, isoCode, countryName. Please note that filtering is not possible for fields deeper in the object JSON. In the example, fields of the object supportedLanguages does not support filtering

    Sorting

    Example Use of sorting

    curl "https://api.researchnow.com/sample/v1/countries?sort=countryName:desc,isoCode:asc"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    option := &samplify.QueryOptions{
      SortBy: []*samplify.Sort{
        &samplify.Sort{Field: samplify.QueryFieldCountryName, Direction: samplify.SortDirectionDesc},
        &samplify.Sort{Field: samplify.QueryFieldIsoCode, Direction: samplify.SortDirectionAsc},
      },
    }
    res, err := client.GetCountries(option)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    var option = new QueryOptions();
    option.AddSort("countryName", SortDirection.Desc);
    option.AddSort("isoCode", SortDirection.Asc);
    
    try
    {
        var res = await client.GetCountries(option);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response

    {
      "data": [
        {
          "id": "US",
          "isoCode": "US",
          "countryName": "United States of America",
          "supportedLanguages": [
            {
              "id": "en_US",
              "isoCode": "en_US",
              "languageName": "English (US)"
            },
            {
              "id": "es_US",
              "isoCode": "es_US",
              "languageName": "Spanish (US)"
            }
          ]
        },
        {
          "id": "GB",
          "isoCode": "GB",
          "countryName": "United Kingdom",
          "supportedLanguages": [
            {
              "id": "en_GB",
              "isoCode": "en_GB",
              "languageName": "English (UK)"
            }
          ]
        },
        ...
      ]
    }
    

    All GET endpoints which return an object list supports sorting. Sorting can be done by specifying sort in the query parameters along with the fields you want to sort. For the example in the right, sorting can be done for all first level fields: id, isoCode, countryName. Please note that sorting is not possible for fields deeper in the object JSON. In the example, fields of the object supportedLanguages does not support sorting

    Sorting can be done for multiple fields in the same request, by separating the fields with a comma. Order is dependent on the order of how the fields were specified. In the example sorting would be first by countryName and then by isoCode.

    Sorting Formats

    Format Description
    asc Sorts the object list in ascending order of the specified field
    desc Sorts the object list in descending order of the specified field

    Start & End Links

    Example Start Link Clients provide

    "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>"
    

    Example Survey link when respondent goes in

    "surveyURL": "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw**"
    

    Start link is the survey link that you want respondents to go into to take the survey. Dynata appends certain fields on the survey URL so that you can capture the data and send it back to us in the end link for marking an end to the respondents session.

    Append Fields

    Parameter Description
    pid Dynata's unique respondent identifier. We will automatically append the pid to the survey URL when a respondent starts the survey. The pid is numeric and will be up to 10 digits in length
    psid Dynata's unique identifier that captures a respondent and the specific project identifier. We will automatically append the psid to the survey URL when a respondent starts the survey. The psid tag will always be lowercase. The value of the psid is alphanumeric, a maximum length of 64 digits and will contain asterisks, and other special characters, such as dashes and underscores, which must be supported by the survey programming platform. You need to pass the psid back in the end link
    k2 A security key passed to you in the survey URL. This is required for calculating the med value in the end link. Replace this with the survey_key_2 in the med calculation

    Supported endlinks:

    {
        "endLinks": {
          "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
          "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
          "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}"
        }
    }
    

    Example med calculation:

    med = (66213 * value for pid ) - security_key_2
    
    For a respondent with pid=1070000026, security_key_2=59931, the value would be:
    
    med = (66213 * 1070000026 ) - 59931 = 70847911661607
    

    After the respondent completes the survey, they should be redirected to a secure exit redirect link. These links give the respondent the proper information and allow Dynata, and you, to properly record and count the status of all the respondents that take your survey. Your survey must be updated and tested with these links before launching the survey.

    Query Parameters

    Parameter Description
    rst The flag for respondent's session end. 1 = Complete, 2 = screenout, 3 = overquota
    psid Dynata's unique identifier that captures a respondent and the specific project identifier. This was passed to you in the survey URL when the respondent goes in.
    med The secure variable which Dynata validates before updating the respondent's status for the session.

    The med parameter can be generated as follows:

    med = (security_key_1 * pid) – security_key_2

    Fields for med calculation

    Parameter Description
    pid Dynata's respondent identifier. This is a unique id passed to you in the survey URL when the respondent goes in
    security_key_1 A security key provided to you during onboarding. Please do not share this with anyone
    security_key_2 A security key (k2) passed to you in the survey URL. This is unique per respondent per project

    Core Resources

    Projects

    Create Project

    Example Request

    curl 'https://api.researchnow.com/sample/v1/projects'
      -X POST \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <Access-Token>' \
      -d '{
        "extProjectId": "project001",
        "title": "Test Survey",
        "notificationEmails": [
          "api-test@dynata.com"
        ],
        "devices": [
          "mobile",
          "desktop",
          "tablet"
        ],
        "category": {
          "surveyTopic": [
            "AUTOMOTIVE",
            "BUSINESS"
          ]
        },
        "lineItems": [
          {
            "extLineItemId": "lineItem001",
            "title": "US College",
            "countryISOCode": "US",
            "languageISOCode": "en",
            "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
            "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
            "indicativeIncidence": 20,
            "daysInField": 20,
            "lengthOfInterview": 10,
            "deliveryType": "BALANCED",
            "requiredCompletes": 200,
            "quotaPlan": {
              "filters": [
                {
                  "attributeId": "4091",
                  "options": [
                    "3",
                    "4"
                  ]
                }
              ],
              "quotaGroups": [
                {
                  "name": "Gender Distribution",
                  "quotaCells": [
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "1"
                          ]
                        }
                      ],
                      "count": 130
                    },
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "2"
                          ]
                        }
                      ],
                      "count": 70
                    }
                  ]
                }
              ]
            }
          }
        ],
        "exclusions": {
          "type": "PROJECT",
          "list": []
        }
      }'
    
    client := samplify.NewClient("client_id", "username", "password")
    p := &samplify.CreateProjectCriteria{
      ExtProjectID:       "project001",
      Title:              "Test Survey",
      NotificationEmails: []string{"api-test@dynata.com"},
      Devices:            []samplify.DeviceType{samplify.DeviceTypeMobile, samplify.DeviceTypeDesktop},
      Category:           &samplify.Category{SurveyTopic: []string{"AUTOMOTIVE", "BUSINESS"}},
      LineItems:          []*samplify.CreateLineItemCriteria{ln}, // where `ln` is &samplify.CreateLineItemCriteria
      Exclusions:         &samplify.Exclusions{Type: samplify.ExclusionTypeProject, List: []string{"..."}},
    }
    res, err := client.CreateProject(p)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    var p = new ProjectCriteria
    {
        ExtProjectID = "project001",
        Title = "Test Survey",
        NotificationEmails = new string[] { "api-test@dynata.com" },
        Devices = new string[] { DeviceTypeConstants.DeviceTypeMobile, DeviceTypeConstants.DeviceTypeDesktop },
        Category = new Category
        {
            SurveyTopic = new string[] { "AUTOMOTIVE", "BUSINESS" }
        },
        LineItems = new LineItemCriteria[] { ln },  // where `ln` is LineItemCriteria
        Exclusions = new Exclusions
        {
            Type = ExclusionTypeConstants.ExclusionTypeProject,
            List = new string[] { "..." }
        }
    };
    
    try
    {
        var res = await client.CreateProject(p);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extProjectId": "project001",
        "title": "Test Survey",
        "notificationEmails": [
          "api-test@dynata.com"
        ],
        "devices": [
          "mobile",
          "desktop",
          "tablet"
        ],
        "category": {
          "surveyTopic": [
            "AUTOMOTIVE",
            "BUSINESS"
          ]
        },
        "lineItems": [
          {
            "extLineItemId": "lineItem001",
            "title": "US College",
            "countryISOCode": "US",
            "languageISOCode": "en",
            "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
            "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
            "indicativeIncidence": 20,
            "daysInField": 20,
            "lengthOfInterview": 10,
            "deliveryType": "BALANCED",
            "requiredCompletes": 200,
            "quotaPlan": {
              "filters": [
                {
                  "attributeId": "4091",
                  "options": [
                    "3",
                    "4"
                  ]
                }
              ],
              "quotaGroups": [
                {
                  "name": "Gender Distribution",
                  "quotaCells": [
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "1"
                          ]
                        }
                      ],
                      "count": 130
                    },
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "2"
                          ]
                        }
                      ],
                      "count": 70
                    }
                  ]
                }
              ]
            },
            "state": "PROVISIONED",
            "stateReason": "Created by Client",
            "stateLastUpdatedAt": "04/01/2018 00:00:00",
            "createdAt": "04/01/2018 00:00:00",
            "updatedAt": "04/01/2018 00:00:00",
            "launchedAt": null,
            "endLinks": {
              "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
              "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
              "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}",
              "securityKey1": "35040",
              "securityLevel": "MEDIUM"
            }
          }
        ],
        "exclusions": {
          "type": "PROJECT",
          "list": []
        },
        "state": "PROVISIONED",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/01/2018 00:00:00"
      }
    }
    

    Creating a project is the first step to launching your surveys to Dynata panelists.

    HTTP Request

    POST /projects

    Request Parameters

    Parameter Type Field Description
    extProjectId String Required A unique identifier for your project
    title String Required A project title of your choosing
    notificationEmails List Required The email addresses to receive notifications
    devices List Required Device targeting for the project: mobile, desktop, tablet
    category.surveyTopic List, enumerable Required List of possible topics for a survey. Please see Categories
    lineItems List Required Please see the Add Line Item endpoint
    exclusions.type String, enumerable Optional The type of Exclusion: PROJECT
    exclusions.list List Optional List of previous extProjectId that you want to exclude

    Response

    Returns the project object with additional fields as below.

    Parameter Description
    state The current state of the project: PROVISIONED, CANCELLED, LAUNCHED, CLOSED, INVOICED
    stateLastUpdatedAt Timestamp of when the project last changed its state
    createdAt Timestamp of when the project was created
    updatedAt Timestamp of when the project was updated

    Update Project

    Example Request

    curl 'https://api.researchnow.com/sample/v1/projects/project001'
      -X POST \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <Access-Token>' \
      -d '{
        "title": "Automobile Survey",
        "devices": [
          "mobile"
        ],
        "category": {
          "surveyTopic": [
            "AUTOMOTIVE",
            "BUSINESS",
            "EDUCATION"
          ]
        },
        "exclusions": {
          "type": "PROJECT",
          "list": ["project002"]
        }
      }'
    
    client := samplify.NewClient("client_id", "username", "password")
    title := "Automobile Survey"
    p := &samplify.UpdateProjectCriteria{
      ExtProjectID: "project001",
      Title:        &title,
      Devices:      &[]samplify.DeviceType{samplify.DeviceTypeMobile},
      Category:     &samplify.Category{SurveyTopic: []string{"AUTOMOTIVE", "BUSINESS", "EDUCATION"}},
      Exclusions:   &samplify.Exclusions{Type: samplify.ExclusionTypeProject, List: []string{"project002"}},
    }
    res, err := client.UpdateProject(p)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    var p = new ProjectCriteria
    {
        ExtProjectID = "project001",
        Title = "Automobile Survey",
        Devices = new string[] { DeviceTypeConstants.DeviceTypeMobile },
        Category = new Category
        {
            SurveyTopic = new string[] { "AUTOMOTIVE", "BUSINESS", "EDUCATION" }
        },
        Exclusions = new Exclusions
        {
            Type = ExclusionTypeConstants.ExclusionTypeProject,
            List = new string[] { "project002" }
        }
    };
    
    try
    {
        var res = await client.UpdateProject(p);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extProjectId": "project001",
        "title": "Automobile Survey",
        "notificationEmails": [
          "api-test@dynata.com"
        ],
        "devices": [
          "mobile"
        ],
        "category": {
          "surveyTopic": [
            "AUTOMOTIVE",
            "BUSINESS",
            "EDUCATION"
          ]
        },
        "lineItems": [
          {
            "extLineItemId": "lineItem001",
            "title": "US College",
            "countryISOCode": "US",
            "languageISOCode": "en",
            "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
            "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
            "indicativeIncidence": 20,
            "daysInField": 20,
            "lengthOfInterview": 10,
            "requiredCompletes": 200,
            "quotaPlan": {
              "filters": [
                {
                  "attributeId": "4091",
                  "options": [
                    "3",
                    "4"
                  ]
                }
              ],
              "quotaGroups": [
                {
                  "name": "Gender Distribution",
                  "quotaCells": [
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "1"
                          ]
                        }
                      ],
                      "count": 130
                    },
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "2"
                          ]
                        }
                      ],
                      "count": 70
                    }
                  ]
                }
              ]
            },
            "state": "PROVISIONED",
            "stateReason": "Created by Client",
            "stateLastUpdatedAt": "04/01/2018 00:00:00",
            "createdAt": "04/01/2018 00:00:00",
            "updatedAt": "04/01/2018 00:00:00",
            "launchedAt": null,
            "endLinks": {
              "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
              "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
              "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}",
              "securityKey1": "35040",
              "securityLevel": "MEDIUM"
            }
          }
        ],
        "exclusions": {
          "type": "PROJECT",
          "list": [
            "project002"
          ]
        },
        "state": "PROVISIONED",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/01/2018 00:00:00"
      }
    }
    

    Updates the specified project by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

    HTTP Request

    POST /projects/{extProjectId}

    Request Parameters

    Parameters updateable in PROVISIONED state only

    Parameter Type Field Description
    title String Optional A project title of your choosing
    notificationEmails List Optional The email addresses to receive notifications
    devices List Optional Device targeting for the project: mobile, desktop, tablet
    category.surveyTopic List, enumerable Optional List of possible topics for a survey. Please see Categories
    lineItems List Optional Please see the Add Line Item endpoint
    exclusions.type String, enumerable Optional The type of Exclusion: PROJECT
    exclusions.list List Optional List of Project Ids

    Response

    Returns the updated project object with additional fields as below.

    Parameter Description
    state The current state of the project: PROVISIONED, CANCELLED, LAUNCHED, CLOSED, INVOICED
    stateLastUpdatedAt Timestamp of when the project last changed its state
    createdAt Timestamp of when the project was created
    updatedAt Timestamp of when the project was updated

    Buy Project

    Example Request

    curl 'https://api.researchnow.com/sample/v1/projects/project001/buy'
      -X POST \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <Access-Token>' \
      -d '[
          {
            "extLineItemId": "lineItem001",
            "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
            "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>"
          },
          {
            "extLineItemId": "lineItem002",
            "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
            "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>"
          }
        ]
      '
    
    client := samplify.NewClient("client_id", "username", "password")
    buyOne := &samplify.BuyProjectCriteria{
      ExtLineItemID: "lineItem001",
      SurveyURL:     "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
      SurveyTestURL: "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
    }
    buyTwo := &samplify.BuyProjectCriteria{
      ExtLineItemID: "lineItem002",
      SurveyURL:     "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
      SurveyTestURL: "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
    }
    res, err := client.BuyProject("project001", []*samplify.BuyProjectCriteria{buyOne, buyTwo})
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    var buyReq = new BuyProjectCriteria[]
    {
        new BuyProjectCriteria
        {
            ExtLineItemID = "lineItem001",
            SurveyURL = "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
            SurveyTestURL = "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw"
        },
        new BuyProjectCriteria
        {
            ExtLineItemID = "lineItem002",
            SurveyURL = "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
            SurveyTestURL = "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw"
        }
    };
    
    try
    {
        var res = await client.BuyProject("project001", buyReq);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": [
        {
          "extLineItemId": "lineItem001",
          "state": "AWAITING_APPROVAL"
        },
        {
          "extLineItemId": "lineItem002",
          "state": "AWAITING_APPROVAL"
        }
      ]
    }
    

    Buy the line items for a project, agreeing to the price.

    HTTP Request

    POST /projects/{extProjectId}/buy

    Request Parameters

    Parameter Type Field Description
    extLineItemId String Required A unique identifier for your Line Item
    surveyURL String Required Survey URL to send panelist into. Please see Start & End Links
    surveyTestURL String Required Survey Test URL. Required for survey verification

    Response

    Parameter Description
    extLineItemId A unique identifier for your Line Item
    state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, PAUSED, CLOSED, CANCELLED, INVOICED

    Close Project

    Example Request

    curl 'https://api.researchnow.com/sample/v1/projects/project001/close'
      -X POST \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <Access-Token>'
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.CloseProject("project001")
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.CloseProject("project001");
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extProjectId": "project001",
        "state": "CLOSED",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/01/2018 00:00:00",
        "lineItems": [
          {
            "extLineItemId": "lineItem001",
            "state": "CLOSED",
            "stateReason": "Closed by Client",
            "stateLastUpdatedAt": "04/01/2018 00:00:00",
            "createdAt": "04/01/2018 00:00:00",
            "updatedAt": "04/01/2018 00:00:00",
            "launchedAt": "04/01/2018 00:00:00"
          }
        ]
      }
    }
    

    Closes the requested project. Once a project is closed, all traffic is stopped, and the project is automatically sent for invoicing.

    HTTP Request

    POST /projects/{extProjectId}/{action}

    Actions

    Parameter Description
    close Stops traffic to all line items and closes the project. Once a project is closed it cannot be launched again.

    Response

    Returns the updated project and line item states.

    Parameter Description
    extProjectId A unique identifier for your project
    state The current state of the project: PROVISIONED, CANCELLED, LAUNCHED, CLOSED, INVOICED
    stateLastUpdatedAt Timestamp of when the project last changed its state
    createdAt Timestamp of when the project was created
    updatedAt Timestamp of when the project was updated
    lineItems[].extProjectId A unique identifier for your Project
    lineItems[].state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, PAUSED, CLOSED, CANCELLED, INVOICED
    lineItems[].stateReason Reason for the current state of the line item
    lineItems[].stateLastUpdatedAt Timestamp of when the line item last changed its state
    lineItems[].createdAt Timestamp of when the line item was created
    lineItems[].updatedAt Timestamp of when the line item was updated
    lineItems[].launchedAt Timestamp of when the line item launched on Dynata panelists

    Get All Projects

    Example Request

    curl "https://api.researchnow.com/sample/v1/projects"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetAllProjects(nil)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetAllProjects(null);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": [
        {
          "extProjectId": "project001",
          "title": "Automotive Study",
          "state": "LAUNCHED",
          "stateLastUpdatedAt": "04/01/2018 00:00:00",
          "createdAt": "04/01/2018 00:00:00",
          "updatedAt": "04/01/2018 00:00:00"
        },
        {
          "extProjectId": "project002",
          "title": "Beverage Study",
          "state": "PROVISIONED",
          "stateLastUpdatedAt": "04/01/2018 00:00:00",
          "createdAt": "04/01/2018 00:00:00",
          "updatedAt": "04/01/2018 00:00:00"
        },
        {
          "extProjectId": "project003",
          "title": "Concept Test",
          "state": "CLOSED",
          "stateLastUpdatedAt": "04/01/2018 00:00:00",
          "createdAt": "04/01/2018 00:00:00",
          "updatedAt": "04/01/2018 00:00:00"
        },
        ...
      ]
    }
    

    Returns you the list of projects

    HTTP Request

    GET /projects

    Response

    Returns the project list with below fields

    Parameter Description
    extProjectId A unique identifier for your project
    title A project title of your choosing
    state The current state of the project: PROVISIONED, CANCELLED, LAUNCHED, COMPLETED, CLOSED, INVOICED
    stateLastUpdatedAt Timestamp of when the project last changed its state
    createdAt Timestamp of when the project was created
    updatedAt Timestamp of when the project was updated

    Get Specific Project

    Example Request

    curl "https://api.researchnow.com/sample/v1/projects/project001"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetProjectBy("project001")
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetProjectBy("project001");
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extProjectId": "project001",
        "title": "Test Survey",
        "notificationEmails": [
          "api-test@dynata.com"
        ],
        "devices": [
          "mobile",
          "desktop",
          "tablet"
        ],
        "category": {
          "surveyTopic": [
            "AUTOMOTIVE",
            "BUSINESS"
          ]
        },
        "lineItems": [
          {
            "extLineItemId": "lineItem001",
            "title": "US College",
            "countryISOCode": "US",
            "languageISOCode": "en",
            "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
            "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
            "indicativeIncidence": 20,
            "daysInField": 20,
            "lengthOfInterview": 10,
            "deliveryType": "BALANCED",
            "requiredCompletes": 200,
            "quotaPlan": {
              "filters": [
                {
                  "attributeId": "4091",
                  "options": [
                    "3",
                    "4"
                  ]
                }
              ],
              "quotaGroups": [
                {
                  "name": "Gender Distribution",
                  "quotaCells": [
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "1"
                          ]
                        }
                      ],
                      "count": 130
                    },
                    {
                      "quotaNodes": [
                        {
                          "attributeId": "11",
                          "options": [
                            "2"
                          ]
                        }
                      ],
                      "count": 70
                    }
                  ]
                }
              ]
            },
            "state": "PROVISIONED",
            "stateReason": "Created by Client",
            "stateLastUpdatedAt": "04/01/2018 00:00:00",
            "createdAt": "04/01/2018 00:00:00",
            "updatedAt": "04/01/2018 00:00:00",
            "launchedAt": null,
            "endLinks": {
              "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
              "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
              "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}",
              "securityKey1": "35040",
              "securityLevel": "MEDIUM"
            }
          }
        ],
        "exclusions": {
          "type": "PROJECT",
          "list": []
        },
        "state": "LAUNCHED",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/01/2018 00:00:00"
      }
    }
    

    Returns you the requested project based on the id

    HTTP Request

    GET /projects/{extProjectId}

    Response

    Returns the project object with additional fields as below.

    Parameter Description
    extProjectId A unique identifier for your project
    title A project title of your choosing
    notificationEmails The email addresses to receive notifications
    devices Device targeting for the project: mobile, desktop, tablet
    category.surveyTopic List of possible topics for a survey. Please see Categories
    lineItems List of line item objects
    exclusions.type The type of Exclusion: PROJECT
    exclusions.list List of extProjectId excluded from this project
    state The current state of the project: PROVISIONED, CANCELLED, LAUNCHED, CLOSED, INVOICED
    stateLastUpdatedAt Timestamp of when the project last changed its state
    createdAt Timestamp of when the project was created
    updatedAt Timestamp of when the project was updated

    Get Project Report

    Example Request

    curl "https://api.researchnow.com/sample/v1/projects/project001/report"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetProjectReport("project001")
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetProjectReport("project001");
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extProjectId": "project001",
        "title": "Automotive Study",
        "state": "LAUNCHED",
        "attempts": 300,
        "completes": 100,
        "screenouts": 100,
        "overquotas": 100,
        "starts": 700,
        "conversion": 30.0,
        "currency": "USD",
        "remainingCompletes": 200,
        "actualMedianLOI": 20,
        "incurredCost": 2000.53,
        "estimatedCost": 3500.00,
        "lineItems": [
          {
            "extLineItemId": "lineItem001",
            "title": "US College",
            "countryISOCode": "US",
            "languageISOCode": "en",
            "state": "LAUNCHED",
            "attempts": 200,
            "completes": 80,
            "overquotas": 60,
            "screenouts": 30,
            "starts": 30,
            "conversion": 40.0,
            "currency": "USD",
            "remainingCompletes": 50,
            "actualMedianLOI": 20,
            "incurredCost": 1600.53,
            "estimatedCost": 2500.00,
            "lastAcceptedIncidenceRate": 123.45,
            "lastAcceptedLOI": 20
          },
          {
            "extLineItemId": "lineItem002",
            "title": "Young Teens",
            "countryISOCode": "CA",
            "languageISOCode": "en",
            "state": "PAUSED",
            "attempts": 100,
            "completes": 20,
            "overquotas": 40,
            "screenouts": 30,
            "starts": 10,
            "conversion": 20.0,
            "currency": "USD",
            "remainingCompletes": 50,
            "actualMedianLOI": 20,
            "incurredCost": 400.00,
            "estimatedCost": 1000.00,
            "lastAcceptedIncidenceRate": 11.22,
            "lastAcceptedLOI": 25
          }
        ]
      }
    }
    

    Returns you the current project report based on observed data from actual panelists

    HTTP Request

    GET /projects/{extProjectId}/report

    Response

    Returns the project object with additional fields as below.

    Parameter Description
    extProjectId A unique identifier for your project
    title A project title of your choosing
    state The current state of the project: PROVISIONED, CANCELLED, LAUNCHED, CLOSED, INVOICED
    attempts Total number of panelists that entered the project
    completes Total number of panelists that completed the project
    screenouts Total number of panelists that got screened out of the project
    overquotas Total number of panelists that triggered an overquota for the project
    starts Total number of panelists currently in the project taking a survey
    conversion Ratio of completes over attempts. (ranges from 0%-100%)
    currency Currency associated with the costs
    remainingCompletes Total remaining completes for the project
    actualMedianLOI Calculated median length of interview from actual panelists
    incurredCost Incurred cost for the project till now
    estimatedCost Estimated cost for the whole project
    lineItems[].extLineItemId A unique identifier for your line item
    lineItems[].title A Line Item title of your choosing
    lineItems[].countryISOCode 2 letter ISO Country Code
    lineItems[].languageISOCode 2 letter ISO Language Code
    lineItems[].state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, PAUSED, CLOSED, CANCELLED, INVOICED
    lineItems[].attempts Total number of panelists that entered the line item
    lineItems[].completes Total number of panelists that completed the line item
    lineItems[].overquotas Total number of panelists that got screened out of the line item
    lineItems[].screenouts Total number of panelists that triggered an overquota for the line item
    lineItems[].starts Total number of panelists currently in the line item taking a survey
    lineItems[].conversion Ratio of completes over attempts for the line item. (ranges from 0%-100%)
    lineItems[].currency Currency associated with the costs
    lineItems[].remainingCompletes Total remaining completes for the line item
    lineItems[].actualMedianLOI Calculated median length of interview from actual panelists that qualified as part of this line item
    lineItems[].incurredCost Incurred cost for the line item till now
    lineItems[].estimatedCost Estimated cost for the line item
    lineItems[].lastAcceptedIncidenceRate Last accepted incidence rate for the line item
    lineItems[].lastAcceptedLOI Last accepted length of interview for the line item

    Line Items

    Add Line Item

    Example Request

    curl 'https://api.researchnow.com/sample/v1/projects/project001/lineItems'
      -X POST \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <Access-Token>' \
      -d '{
        "extLineItemId": "lineItem001",
        "title": "US College",
        "countryISOCode": "US",
        "languageISOCode": "en",
        "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
        "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
        "indicativeIncidence": 20,
        "daysInField": 20,
        "lengthOfInterview": 10,
        "deliveryType": "BALANCED",
        "requiredCompletes": 200,
        "quotaPlan": {
          "filters": [
            {
              "attributeId": "4091",
              "options": [
                "3",
                "4"
              ]
            }
          ],
          "quotaGroups": [
            {
              "name": "Gender Distribution",
              "quotaCells": [
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "1"
                      ]
                    }
                  ],
                  "count": 130
                },
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "2"
                      ]
                    }
                  ],
                  "count": 70
                }
              ]
            }
          ]
        }
      }'
    
    client := samplify.NewClient("client_id", "username", "password")
    surveyURL := "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw"
    surveyTestURL := "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw"
    lineitem := &samplify.CreateLineItemCriteria{
      ExtLineItemID:       "lineItem001",
      Title:               "US College",
      CountryISOCode:      "US",
      LanguageISOCode:     "en",
      SurveyURL:           &surveyURL,
      SurveyTestURL:       &surveyTestURL,
      IndicativeIncidence: 20.0,
      DaysInField:         20,
      LengthOfInterview:   10,
      RequiredCompletes:   200,
      QuotaPlan: &samplify.QuotaPlan{
        Filters: []*samplify.QuotaFilters{
          &samplify.QuotaFilters{AttributeID: "4091", Options: []string{"3", "4"}},
        },
        QuotaGroups: []*samplify.QuotaGroup{
          &samplify.QuotaGroup{
            Name: "Gender distribution",
            QuotaCells: []*samplify.QuotaCell{
              &samplify.QuotaCell{
                QuotaNodes: []*samplify.QuotaNode{
                  &samplify.QuotaNode{AttributeID: "11", OptionIDs: []string{"1"}},
                },
                Count: 130,
              },
              &samplify.QuotaCell{
                QuotaNodes: []*samplify.QuotaNode{
                  &samplify.QuotaNode{AttributeID: "11", OptionIDs: []string{"2"}},
                },
                Count: 70,
              },
            },
          },
        },
      },
    }
    res, err := client.AddLineItem("project001", lineitem)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    
    var filters = new QuotaFilters[]
    {
        new QuotaFilters
        {
            AttributeID = "4091",
            Options = new string[] {"3", "4"}
        }
    };
    
    var quotaGroups = new QuotaGroup[]
    {
        new QuotaGroup
        {
            Name = "Gender distribution",
            QuotaCells = new QuotaCell[]
            {
                new QuotaCell
                {
                    QuotaNodes = new QuotaNode[] {new QuotaNode{AttributeID = "11", OptionIDs = new string[]{"1"}}},
                    Count=130
                },
                new QuotaCell
                {
                    QuotaNodes = new QuotaNode[] {new QuotaNode{AttributeID = "11", OptionIDs = new string[]{"2"}}},
                    Count=70
                }
            }
        }
    };
    
    var lineitem = new LineItemCriteria
    {
        ExtLineItemID = "lineItem001",
        Title = "US College",
        CountryISOCode = "US",
        LanguageISOCode = "en",
        SurveyURL = "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
        SurveyTestURL = "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
        IndicativeIncidence = 20.0M,
        DaysInField = 20,
        LengthOfInterview = 10,
        RequiredCompletes = 200,
        QuotaPlan = new QuotaPlan
        {
            Filters = filters,
            QuotaGroups = quotaGroups
        }
    };
    
    try
    {
        var res = await client.AddLineItem("project001", lineitem);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extLineItemId": "lineItem001",
        "title": "US College",
        "countryISOCode": "US",
        "languageISOCode": "en",
        "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
        "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
        "indicativeIncidence": 20.0,
        "daysInField": 20,
        "lengthOfInterview": 10,
        "deliveryType": "BALANCED",
        "requiredCompletes": 200,
        "quotaPlan": {
          "filters": [
            {
              "attributeId": "4091",
              "options": [
                "3",
                "4"
              ]
            }
          ],
          "quotaGroups": [
            {
              "name": "Gender Distribution",
              "quotaCells": [
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "1"
                      ]
                    }
                  ],
                  "count": 130
                },
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "2"
                      ]
                    }
                  ],
                  "count": 70
                }
              ]
            }
          ]
        },
        "state": "PROVISIONED",
        "stateReason": "Created by Client",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/01/2018 00:00:00",
        "launchedAt": null,
        "endLinks": {
          "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
          "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
          "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}",
          "securityKey1": "35040",
          "securityLevel": "MEDIUM"
        }
      }
    }
    

    A line item is a project entity that exist for a specific market and language that your survey is aimed at. It defines the target panelists for the market that the survey is looking for, and the number of completes required. A line item is our unit of work and is what gets billed to you

    HTTP Request

    POST /projects/{extProjectId}/lineItems

    Request Parameters

    Parameter Type Field Description
    extLineItemId String Required A unique identifier for your Line Item
    title String Required A Line Item title of your choosing
    countryISOCode String Required 2 letter ISO Country Code
    languageISOCode String Required 2 letter ISO Language Code
    surveyURL String Optional Survey URL to send panelist into. Please see Start & End Links
    surveyTestURL String Optional Survey Test URL. Required for survey verification
    indicativeIncidence Float Required Percent of panelists you expect to qualify for the survey after they go in
    daysInField Integer Required Number of days the survey should be active in the field. We do not stop the survey after daysInField has expired
    lengthOfInterview Integer Required Average number of minutes it takes a user to complete your survey
    deliveryType List, enumerable Optional The plan on how responses will flow into the survey. Please see the table below on Delivery Types for explanations. We support the following types - SLOW, BALANCED, FAST.
    requiredCompletes Integer Required Total number of completes required for this line item
    quotaPlan.filters Hash Optional Filters are attributes which all panelists should have before qualifying for a survey. Only attributes that have isAllowedInFilters = true is allowed. Please see Quota Plan Guidelines
    quotaPlan.quotaGroups List Optional Quota groups define the allocated targeting attributes for panelists within this line item. Only attributes that have isAllowedInQuotas = true is allowed. Please see Quota Plan Guidelines

    Delivery Types

    Explanation of the delivery types supported in a line item:

    Parameter Description
    SLOW Spreads responses evenly over the full field time
    BALANCED ~75% of your needed project completes in the first ½ of field time with the second ½ of field picking up the last 25% of the needed completes. This is the default option if you do not specify a deliveryType
    FAST Responses will be accelerated in an effort to get your project as many completes as fast as possible

    Response

    Returns the line item object with additional fields as below.

    Parameter Description
    state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, AWAITING_CLIENT_APPROVAL, PAUSED, CLOSED, CANCELLED, INVOICED
    stateReason Reason for the current state of the line item
    stateLastUpdatedAt Timestamp of when the line item last changed its state
    createdAt Timestamp of when the line item was created
    updatedAt Timestamp of when the line item was updated
    launchedAt Timestamp of when the line item LAUNCHED on Dynata panelists
    endLinks.complete Redirect URL where you should send respondents to after they complete the survey successfully. Please see Start & End Links
    endLinks.screenout Redirect URL where you should send respondents to if they disqualified from the survey based on screening questions. Please see Start & End Links
    endLinks.overquota Redirect URL where you should send respondents to if line item was already filled. Please see Start & End Links
    endLinks.securityKey1 Security Key to use for the med calculation of survey end links. Please see Start & End Links
    endLinks.securityLevel The level of security set for your account to call the survey end links. By default its always MEDIUM

    Update Line Item

    Example Request

    curl 'https://api.researchnow.com/sample/v1/projects/project001/lineItems/lineItem001'
      -X POST \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <Access-Token>' \
      -d '{
          "title": "US College",
          "countryISOCode": "US",
          "languageISOCode": "en",
          "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
          "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
          "indicativeIncidence": 15.0,
          "daysInField": 22,
          "lengthOfInterview": 12,
          "deliveryType": "BALANCED",
          "requiredCompletes": 200,
          "quotaPlan": {
            "filters": [
              {
                "attributeId": "4091",
                "options": [
                  "3",
                  "4"
                ]
              }
            ],
            "quotaGroups": [
              {
                "name": "Gender Distribution",
                "quotaCells": [
                  {
                    "quotaNodes": [
                      {
                        "attributeId": "11",
                        "options": [
                          "1"
                        ]
                      }
                    ],
                    "count": 130
                  },
                  {
                    "quotaNodes": [
                      {
                        "attributeId": "11",
                        "options": [
                          "2"
                        ]
                      }
                    ],
                    "count": 70
                  }
                ]
              }
            ]
          }
        }'
    
    client := samplify.NewClient("client_id", "username", "password")
    title := "US College"
    countryISOCode := "US"
    languageISOCode := "en"
    surveyURL := "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw"
    surveyTestURL := "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw"
    lineitem := &samplify.UpdateLineItemCriteria{
      ExtLineItemID:       "lineItem001",
      Title:           &title,
      CountryISOCode:  &countryISOCode,
      LanguageISOCode: &languageISOCode,
      SurveyURL:       &surveyURL,
      SurveyTestURL:   &surveyTestURL,
      QuotaPlan: &samplify.QuotaPlan{
        Filters: []*samplify.QuotaFilters{
          &samplify.QuotaFilters{AttributeID: "4091", Options: []string{"3", "4"}},
        },
        QuotaGroups: []*samplify.QuotaGroup{
          &samplify.QuotaGroup{
            Name: "Gender distribution",
            QuotaCells: []*samplify.QuotaCell{
              &samplify.QuotaCell{
                QuotaNodes: []*samplify.QuotaNode{
                  &samplify.QuotaNode{AttributeID: "11", OptionIDs: []string{"1"}},
                },
                Count: 130,
              },
              &samplify.QuotaCell{
                QuotaNodes: []*samplify.QuotaNode{
                  &samplify.QuotaNode{AttributeID: "11", OptionIDs: []string{"2"}},
                },
                Count: 70,
              },
            },
          },
        },
      },
    }
    res, err := client.UpdateLineItem("project001", "lineItem001", lineitem)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    
    var filters = new QuotaFilters[]
    {
        new QuotaFilters
        {
            AttributeID = "4091",
            Options = new string[] {"3", "4"}
        }
    };
    
    var quotaGroups = new QuotaGroup[]
    {
        new QuotaGroup
        {
            Name = "Gender distribution",
            QuotaCells = new QuotaCell[]
            {
                new QuotaCell
                {
                    QuotaNodes = new QuotaNode[] {new QuotaNode{AttributeID = "11", OptionIDs = new string[]{"1"}}},
                    Count=130
                },
                new QuotaCell
                {
                    QuotaNodes = new QuotaNode[] {new QuotaNode{AttributeID = "11", OptionIDs = new string[]{"2"}}},
                    Count=70
                }
            }
        }
    };
    
    var lineitem = new LineItemCriteria
    {
        ExtLineItemID = "lineItem001",
        Title = "US College",
        CountryISOCode = "US",
        LanguageISOCode = "en",
        SurveyURL = "www.mysurvey.com/live/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
        SurveyTestURL = "www.mysurvey.com/test/survey?pid=2424131312&k2=59931&psid=VgrJ2-9iUQZK3noVDtXobw",
        IndicativeIncidence = 15.0M,
        DaysInField = 22,
        LengthOfInterview = 12,
        RequiredCompletes = 200,
        QuotaPlan = new QuotaPlan
        {
            Filters = filters,
            QuotaGroups = quotaGroups
        }
    };
    
    try
    {
        var res = await client.UpdateLineItem("project001", "lineItem001", lineitem);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extLineItemId": "lineItem001",
        "title": "US College",
        "countryISOCode": "US",
        "languageISOCode": "en",
        "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
        "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>",
        "indicativeIncidence": 15.0,
        "daysInField": 22,
        "lengthOfInterview": 12,
        "deliveryType": "BALANCED",
        "requiredCompletes": 200,
        "quotaPlan": {
          "filters": [
            {
              "attributeId": "4091",
              "options": [
                "3",
                "4"
              ]
            }
          ],
          "quotaGroups": [
            {
              "name": "Gender Distribution",
              "quotaCells": [
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "1"
                      ]
                    }
                  ],
                  "count": 130
                },
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "2"
                      ]
                    }
                  ],
                  "count": 70
                }
              ]
            }
          ]
        },
        "state": "PROVISIONED",
        "stateReason": "Created by Client",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/05/2018 00:00:00",
        "launchedAt": null,
        "endLinks": {
          "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
          "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
          "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}",
          "securityKey1": "35040",
          "securityLevel": "MEDIUM"
        }
      }
    }
    

    Updates the specified line item by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

    HTTP Request

    POST /projects/{extProjectId}/lineItems/{extLineItemId}

    Request Parameters

    Parameters updateable in PROVISIONED, AWAITING_APPROVAL state only

    Parameter Type Field Description
    title String Optional A Line Item title of your choosing
    countryISOCode String Optional 2 letter ISO Country Code
    languageISOCode String Optional 2 letter ISO Language Code
    surveyURL String Optional Survey URL to send panelist into. Please see Start & End Links
    surveyTestURL String Optional Survey Test URL. Required for survey verification
    indicativeIncidence Float Optional Percent of panelists you expect to qualify for the survey after they go in
    daysInField Integer Optional Number of days the survey should be active in the field. We do not stop the survey after daysInField has expired
    lengthOfInterview Integer Optional Average number of minutes it takes a user to complete your survey
    deliveryType List, enumerable Optional The plan on how responses will flow into the survey. Please see below on the explanation for each of this type. We support the following types - SLOW, BALANCED, FAST.
    requiredCompletes Integer Optional Total number of completes required for this line item
    quotaPlan.filters Hash Optional Filters are attributes which all panelists should have before qualifying for a survey. Filters are attributes which all panelists should have before qualifying for a survey. Only attributes that have isAllowedInFilters = true is allowed. Please see Quota Plan Guidelines
    quotaPlan.quotaGroups List Optional Quota groups define the allocated targeting attributes for panelists within this line item. Only attributes that have isAllowedInQuotas = true is allowed. Please see Quota Plan Guidelines

    Response

    Returns the updated line item object with additional fields as below.

    Parameter Description
    state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, PAUSED, CLOSED, CANCELLED, INVOICED
    stateReason Reason for the current state of the line item
    stateLastUpdatedAt Timestamp of when the line item last changed its state
    createdAt Timestamp of when the line item was created
    updatedAt Timestamp of when the line item was updated
    launchedAt Timestamp of when the line item LAUNCHED on Dynata panelists
    endLinks.complete Redirect URL where you should send respondents to after they complete the survey successfully. Please see Start & End Links
    endLinks.screenout Redirect URL where you should send respondents to if they disqualified from the survey based on screening questions. Please see Start & End Links
    endLinks.overquota Redirect URL where you should send respondents to if line item was already filled. Please see Start & End Links
    endLinks.securityKey1 Security Key to use for the med calculation of survey end links. Please see Start & End Links
    endLinks.securityLevel The level of security set for your account to call the survey end links. By default its always MEDIUM

    Line Item Actions

    curl 'https://api.researchnow.com/sample/v1/projects/project001/lineItems/lineItem001/pause'
      -X POST \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <Access-Token>'
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.UpdateLineItemState("project001", "lineItem001", samplify.ActionPaused)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.UpdateLineItemState("project001", "lineItem001", ActionConstants.ActionPaused);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extLineItemId": "lineItem001",
        "title": "US College",
        "countryISOCode": "US",
        "languageISOCode": "en",
        "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
        "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
        "indicativeIncidence": 20.0,
        "daysInField": 20,
        "lengthOfInterview": 10,
        "deliveryType": "BALANCED",
        "requiredCompletes": 200,
        "quotaPlan": {
          "filters": [
            {
              "attributeId": "4091",
              "options": [
                "3",
                "4"
              ]
            }
          ],
          "quotaGroups": [
            {
              "name": "Gender Distribution",
              "quotaCells": [
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "1"
                      ]
                    }
                  ],
                  "count": 130
                },
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "2"
                      ]
                    }
                  ],
                  "count": 70
                }
              ]
            }
          ]
        },
        "state": "PAUSED",
        "stateReason": "Paused by Client",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/01/2018 00:00:00",
        "launchedAt": "04/01/2018 00:00:00",
        "endLinks": {
          "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
          "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
          "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}",
          "securityKey1": "35040",
          "securityLevel": "MEDIUM"
        }
      }
    }
    

    Changes the state of the line item based on the action you provide.

    HTTP Request

    POST /projects/{extProjectId}/lineItems/{extLineItemId}/{action}

    Actions

    Parameter Description
    launch Starts traffic to a line item
    pause Stops traffic to a line item
    close Stops traffic to a line item and closes it. Once a line item is closed it cannot be launched again.

    Response

    Returns the line item object with the new state of the line item, if the state transition was successful.

    Parameter Description
    extLineItemId A unique identifier for your Line Item
    title A Line Item title of your choosing
    countryISOCode 2 letter ISO Country Code
    languageISOCode 2 letter ISO Language Code
    surveyURL Survey URL to send panelist into. Please see Start & End Links
    surveyTestURL Survey Test URL. Required for survey verification
    indicativeIncidence Percent of panelists you expect to qualify for the survey after they go in
    daysInField Number of days the survey should be active in the field. We do not stop the survey after daysInField has expired
    lengthOfInterview Average number of minutes it takes a user to complete your survey
    deliveryType The plan on how responses will flow into the survey. Please see below on the explanation for each of this type. We support the following types - SLOW, BALANCED, FAST.
    requiredCompletes Total number of completes required for this line item
    quotaPlan.filters Filters are attributes which all panelists should have before qualifying for a survey
    quotaPlan.quotaGroups Quota groups define the allocated targeting attributes for panelists within this line item
    state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, PAUSED, CLOSED, CANCELLED, INVOICED
    stateReason Reason for the current state of the line item
    stateLastUpdatedAt Timestamp of when the line item last changed its state
    createdAt Timestamp of when the line item was created
    updatedAt Timestamp of when the line item was updated
    launchedAt Timestamp of when the line item launched on Dynata panelists
    endLinks.complete Redirect URL where you should send respondents to after they complete the survey successfully. Please see Start & End Links
    endLinks.screenout Redirect URL where you should send respondents to if they disqualified from the survey based on screening questions. Please see Start & End Links
    endLinks.overquota Redirect URL where you should send respondents to if line item was already filled. Please see Start & End Links
    endLinks.securityKey1 Security Key to use for the med calculation of survey end links. Please see Start & End Links
    endLinks.securityLevel The level of security set for your account to call the survey end links. By default its always MEDIUM

    Get All Line Items

    Example Request

    curl "https://api.researchnow.com/sample/v1/projects/project001/lineItems"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetAllLineItems("project001", nil)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetAllLineItems("project001", null);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": [
        {
          "extLineItemId": "lineItem001",
          "title": "US College",
          "countryISOCode": "US",
          "languageISOCode": "en",
          "state": "PROVISIONED",
          "stateReason": "Created by Client",
          "stateLastUpdatedAt": "04/01/2018 00:00:00",
          "createdAt": "04/01/2018 00:00:00",
          "updatedAt": "04/01/2018 00:00:00",
          "launchedAt": null
        },
        {
          "extLineItemId": "lineItem002",
          "title": "Young Teens",
          "countryISOCode": "CA",
          "languageISOCode": "en",
          "state": "LAUNCHED",
          "stateReason": "Launched by Client",
          "stateLastUpdatedAt": "04/01/2018 00:00:00",
          "createdAt": "04/01/2018 00:00:00",
          "updatedAt": "04/01/2018 00:00:00",
          "launchedAt": "04/01/2018 00:00:00"
        },
        {
          "extLineItemId": "lineItem003",
          "title": "Old High Income",
          "countryISOCode": "JP",
          "languageISOCode": "jp",
          "state": "PAUSED",
          "stateReason": "Paused by Client",
          "stateLastUpdatedAt": "04/01/2018 00:00:00",
          "createdAt": "04/01/2018 00:00:00",
          "updatedAt": "04/01/2018 00:00:00",
          "launchedAt": "04/01/2018 00:00:00"
        },
        ...
      ]
    }
    

    Returns you the requested line item based on the id

    HTTP Request

    GET /projects/{extProjectId}/lineItems

    Response

    Returns the line item list with below fields

    Parameter Description
    extLineItemId A unique identifier for your Line Item
    title A Line Item title of your choosing
    countryISOCode 2 letter ISO Country Code
    languageISOCode 2 letter ISO Language Code
    state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, PAUSED, CLOSED, CANCELLED, INVOICED
    stateReason Reason for the current state of the line item
    stateLastUpdatedAt Timestamp of when the line item last changed its state
    createdAt Timestamp of when the line item was created
    updatedAt Timestamp of when the line item was updated
    launchedAt Timestamp of when the line item launched on Dynata panelists

    Get Specific Line Item

    Example Request

    curl "https://api.researchnow.com/sample/v1/projects/project001/lineItems/lineItem001"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetLineItemBy("project001", "lineItem001")
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetLineItemBy("project001", "lineItem001");
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": {
        "extLineItemId": "lineItem001",
        "title": "US College",
        "countryISOCode": "US",
        "languageISOCode": "en",
        "surveyURL": "www.mysurvey.com/live/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
        "surveyTestURL": "www.mysurvey.com/test/survey?pid=<#DubKnowledge[1500/Entity id]>&k2=<#Project[Secure Key 2]>&psid=<#IdParameter[Value]>",
        "indicativeIncidence": 20.0,
        "daysInField": 20,
        "lengthOfInterview": 10,
        "deliveryType": "BALANCED",
        "requiredCompletes": 200,
        "quotaPlan": {
          "filters": [
            {
              "attributeId": "4091",
              "options": [
                "3",
                "4"
              ]
            }
          ],
          "quotaGroups": [
            {
              "name": "Gender Distribution",
              "quotaCells": [
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "1"
                      ]
                    }
                  ],
                  "count": 130
                },
                {
                  "quotaNodes": [
                    {
                      "attributeId": "11",
                      "options": [
                        "2"
                      ]
                    }
                  ],
                  "count": 70
                }
              ]
            }
          ]
        },
        "state": "LAUNCHED",
        "stateReason": "Launched by Client",
        "stateLastUpdatedAt": "04/01/2018 00:00:00",
        "createdAt": "04/01/2018 00:00:00",
        "updatedAt": "04/01/2018 00:00:00",
        "launchedAt": "04/02/2018 00:00:00",
        "endLinks": {
          "complete": "https://api.researchnow.com/respondent/exit?rst=1&psid={psid}&med={calculatedSecurityCode}",
          "screenout": "https://api.researchnow.com/respondent/exit?rst=2&psid={psid}",
          "overquota": "https://api.researchnow.com/respondent/exit?rst=3&psid={psid}",
          "securityKey1": "35040",
          "securityLevel": "MEDIUM"
        }
      }
    }
    

    Returns you the requested line item based on the id

    HTTP Request

    GET /projects/{extProjectId}/lineItems/{extLineItemId}

    Response

    Returns the line item object with additional fields as below.

    Parameter Description
    extLineItemId A unique identifier for your Line Item
    title A Line Item title of your choosing
    countryISOCode 2 letter ISO Country Code
    languageISOCode 2 letter ISO Language Code
    surveyURL Survey URL to send panelist into. Please see Start & End Links
    surveyTestURL Survey Test URL. Required for survey verification
    indicativeIncidence Percent of panelists you expect to qualify for the survey after they go in
    daysInField Number of days the survey should be active in the field. We do not stop the survey after daysInField has expired
    lengthOfInterview Average number of minutes it takes a user to complete your survey
    deliveryType The plan on how responses will flow into the survey. Please see below on the explanation for each of this type. We support the following types - SLOW, BALANCED, FAST.
    requiredCompletes Total number of completes required for this line item
    quotaPlan.filters Filters are attributes which all panelists should have before qualifying for a survey
    quotaPlan.quotaGroups Quota groups define the allocated targeting attributes for panelists within this line item
    state The current state of the line item: PROVISIONED, AWAITING_APPROVAL, QA_APPROVED, REJECTED, LAUNCHED, PAUSED, CLOSED, CANCELLED, INVOICED
    stateReason Reason for the current state of the line item
    stateLastUpdatedAt Timestamp of when the line item last changed its state
    createdAt Timestamp of when the line item was created
    updatedAt Timestamp of when the line item was updated
    launchedAt Timestamp of when the line item launched on Dynata panelists
    endLinks.complete Redirect URL where you should send respondents to after they complete the survey successfully. Please see Start & End Links
    endLinks.screenout Redirect URL where you should send respondents to if they disqualified from the survey based on screening questions. Please see Start & End Links
    endLinks.overquota Redirect URL where you should send respondents to if line item was already filled. Please see Start & End Links
    endLinks.securityKey1 Security Key to use for the med calculation of survey end links. Please see Start & End Links
    endLinks.securityLevel The level of security set for your account to call the survey end links. By default its always MEDIUM

    Pricing & Feasibility

    Get Pricing & Feasibility

    Example Request:

    curl 'https://api.researchnow.com/sample/v1/projects/project001/feasibility'
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetFeasibility("project001", nil)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetFeasibility("project001", null);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    Example Response(200):

    {
      "data": [
        {
          "extLineItemId": "lineItem001",
          "feasibility": {
            "status": "READY",
            "costPerInterview": 2.14,
            "expiry": "05/01/2018 00:00:00",
            "currency": "USD",
            "feasible": true,
            "totalCount": 50343,
            "valueCounts": [
              {
                "quotaCells": [
                  {
                    "quotaNodes": [
                      {
                        "attributeId": "11",
                        "options": [
                          "1"
                        ]
                      }
                    ],
                    "feasibilityCount": 1000
                  },
                  {
                    "quotaNodes": [
                      {
                        "attributeId": "11",
                        "options": [
                          "2"
                        ]
                      }
                    ],
                    "feasibilityCount": 1200
                  }
                ]
              }
            ]
          }
        },
        {
          "extLineItemId": "lineItem002",
          "feasibility": {
            "status": "PROCESSING",
            "costPerInterview": null,
            "expiry": null,
            "currency": null,
            "feasible": null,
            "totalCount": null,
            "valueCounts": []
          }
        }
      ]
    }
    

    Returns the feasibility for all the line items of the requested project. Feasibility takes 20 - 120 seconds to run, please check the status in the feasibility object to see if it is READY or PROCESSING

    HTTP Request

    GET /projects/{extProjectId}/feasibility

    Response

    Parameter Description
    extLineItemId A unique identifier for your Line Item
    feasibility The feasibility object of the line item
    feasibility.status Current state of feasibility for line item: READY, PROCESSING. If status is PROCESSING please call this request again in 2 mins
    feasibility.costPerInterview Amount Dynata will be paid for each delivered complete
    feasibility.currency Currency associated with the costPerInterview
    feasibility.feasible Can the system deliver the requiredCompletes
    feasibility.totalCount The total completes that we can deliver for the line item within the requested daysInField.
    feasibility.valueCounts The completes that we can deliver for each quotaCell within the requested daysInField. Please note that the structure of the valueCounts object is similar to the quotaGroups structure in Add Line Item

    Notifications

    Events

    Events are how the Dynata platform notifies you about changes that have occured in your project or line item. This includes state transitions on a line item/project like LAUNCHED to PAUSED, LAUNCHED to COMPLETED, AWAITING_APPROVAL to REJECTED, or more critical changes that require your attention such as Study Repricing.

    Events occur when the state of an API resource changes. The changes of that resource at the time of the change is embedded in the event's resource field. For example, a LineItem:RepriceTriggered event will contain all the necessary changes that have occured along with the actions you can take on the event.

    You can get a list of all the events that have occurred in your account, get a specific event, or filter events for specific projects or line items.

    Get All Events

    Example Request

    curl "https://api.researchnow.com/sample/v1/events"
      -H "Authorization: Bearer <Access-Token>"
    
    
    
    
    

    Example Response(200):

    {
      "data": [
        {
          "eventId": 1,
          "eventType": "LineItem:RepriceTriggered",
          "extProjectId": "project001",
          "extLineItemId": "lineItem002",
          "resource": {
            "costPerInterview": {
              "newValue": 212.12,
              "previousValue": 0
            },
            "currency": "USD",
            "estimatedCost": {
              "newValue": 11233.12,
              "previousValue": 53.800003
            },
            "lengthOfInterview": {
              "newValue": 2,
              "previousValue": 5
            },
            "reason": "LOI_CHANGE",
            "status": {
              "newValue": "PAUSED",
              "previousValue": "LAUNCHED"
            }
          },
          "actions": {
            "acceptURL": "https://api.researchnow.com/sample/v1/events/2/accept",
            "rejectURL": "https://api.researchnow.com/sample/v1/events/2/reject"
          },
          "createdAt": "2018/09/25 22:47:36",
        },
        ...
      ]
    }
    

    Returns you the list of all events that have occcured for your company account. Most recent events occur at the top of the list.

    HTTP Request

    GET /events

    Response

    Returns the events list with below fields

    Parameter Description
    eventId A unique identifier for the event
    eventType The type of event. Please see the Types of event and their associated model for more detail about each eventType.
    extProjectId A unique identifier for your project
    extLineItemId A unique identifier for your line item
    resource An object that displays the changes to your resource. The resource is dependent on the eventType. Please see the Types of event and their associated model for more details.
    actions The URL to call to perform an action on the triggered event. Not all events would require you to perform an action, but some eventTypes would. All calls in the actions are POST calls.
    createdAt Timestamp of when the event was created

    Get Specific Event

    Example Request

    curl "https://api.researchnow.com/sample/v1/events/1"
      -H "Authorization: Bearer <Access-Token>"
    
    
    
    
    

    Example Response(200):

    {
      "data":{
        "eventId": 1,
        "eventType": "LineItem:RepriceTriggered",
        "extProjectId": "project001",
        "extLineItemId": "lineItem002",
        "resource": {
          "costPerInterview": {
            "newValue": 212.12,
            "previousValue": 0
          },
          "currency": "USD",
          "estimatedCost": {
            "newValue": 11233.12,
            "previousValue": 53.800003
          },
          "lengthOfInterview": {
            "newValue": 2,
            "previousValue": 5
          },
          "reason": "LOI_CHANGE",
          "status": {
            "newValue": "PAUSED",
            "previousValue": "LAUNCHED"
          }
        },
        "actions": {
          "acceptURL": "https://api.researchnow.com/sample/v1/events/2/accept",
          "rejectURL": "https://api.researchnow.com/sample/v1/events/2/reject"
        },
        "createdAt": "2018/09/25 22:47:36",
      }
    }
    

    Returns you the requested event based on the id

    HTTP Request

    GET /events/{eventId}

    Response

    Returns the events list with below fields

    Parameter Description
    eventId A unique identifier for the event
    eventType The type of event. Please see the Types of event and their associated model for more detail about each eventType.
    extProjectId A unique identifier for your project
    extLineItemId A unique identifier for your line item
    resource An object that displays the changes to your resource. The resource is dependent on the eventType. Please see the Types of event and their associated model for more details.
    actions The URL to call to perform an action on the triggered event. Not all events would require you to perform an action, but some eventTypes would. All calls in the actions are POST calls.
    createdAt Timestamp of when the event was created

    Event Types

    List of eventTypes

    Parameter Description
    LineItem:RepriceTriggered This event will occur when the lengthOfInterview or indicativeIncidence changes beyond a certain threshold during fielding.
    LineItem:RepriceAccepted This event will occur when you have accepted the Repricing approval for a line item
    LineItem:RepriceRejected This event will occur when you have rejected the Repricing approval for a line item

    LineItem:RepriceTriggered event

    {
      "data": [
        {
          "eventId": 1,
          "eventType": "LineItem:RepriceTriggered",
          "extProjectId": "project001",
          "extLineItemId": "lineItem002",
          "resource": {
            "costPerInterview": {
              "newValue": 212.12,
              "previousValue": 0
            },
            "currency": "USD",
            "estimatedCost": {
              "newValue": 11233.12,
              "previousValue": 53.800003
            },
            "lengthOfInterview": {
              "newValue": 2,
              "previousValue": 5
            },
            "reason": "LOI_CHANGE",
            "status": {
              "newValue": "PAUSED",
              "previousValue": "LAUNCHED"
            }
          },
          "actions": {
            "acceptURL": "https://api.researchnow.com/sample/v1/events/2/accept",
            "rejectURL": "https://api.researchnow.com/sample/v1/events/2/reject"
          },
          "createdAt": "2018/09/25 22:47:36",
        },
        ...
      ]
    }
    

    LineItem:RepriceTriggered event

    The LineItem:RepriceTriggered event occurs when the field lengthOfInterview or indicativeIncidence changes beyond your threshold of the initial quoted or last approved price. When a reprice event occurs, the lineItem gets PAUSED as we are awaiting your approval to accept the new price.

    Parameter Description
    eventId A unique identifier for the event
    eventType The type of event.
    extProjectId A unique identifier for your project
    extLineItemId A unique identifier for your line item
    resource.costPerInterview The previous and new value of the costPerInterview
    resource.currency Currency ISO code
    resource.estimatedCost The previous and new value of the estimatedCost
    resource.lengthOfInterview The previous and new value of the lengthOfInterview
    resource.reason The reason that caused this reprice event
    resource.status The previous and new value of the status of Line Item
    actions.acceptURL The URL to call to accept the new price change. Accepting the new price will change the state of the line item from PAUSED to LAUNCHED
    actions.rejectURL The URL to call to reject the new price change. Rejecting the new price will change the state of the line item from PAUSED to CLOSED state.
    createdAt Timestamp of when the event was created

    LineItem:RepriceAccepted event

    {
      "data": [
        {
          "eventId": 2,
          "eventType": "LineItem:RepriceAccepted",
          "extProjectId": "project001",
          "extLineItemId": "lineItem002",
          "parentEventId": 1,
          "resource": {
              "status": {
                  "newValue": "LAUNCHED",
                  "previousValue": "AWAITING_CLIENT_APPROVAL"
              }
          },
          "createdAt": "2018/09/25 23:50:50",
        },
        ...
      ]
    }
    

    LineItem:RepriceAccepted event

    The LineItem:RepriceAccepted event occurs once you have accepted the price change on your lineItem. Accepting the price marks the lineItem as LAUNCHED. The estimatedCost of the project is now based on the new costPerInterview.

    Parameter Description
    eventId A unique identifier for the event
    eventType The type of event.
    extProjectId A unique identifier for your project
    extLineItemId A unique identifier for your line item
    parentEventId The eventId of the LineItem:RepriceTriggered event
    resource.status The previous and new value of the status of Line Item
    createdAt Timestamp of when the event was created

    LineItem:RepriceRejected event

    {
      "data": [
        {
          "eventId": 2,
          "eventType": "LineItem:RepriceRejected",
          "extProjectId": "project001",
          "extLineItemId": "lineItem002",
          "parentEventId": 1,
          "resource": {
              "status": {
                  "newValue": "CLOSED",
                  "previousValue": "AWAITING_CLIENT_APPROVAL"
              }
          },
          "createdAt": "2018/09/25 23:50:50",
        },
        ...
      ]
    }
    

    LineItem:RepriceRejected event

    The LineItem:RepriceRejected event occurs once you have rejected the price change on your lineItem. Rejecting the price marks your lineItem as CLOSED and no further changes can be made on the line item.

    Parameter Description
    eventId A unique identifier for the event
    eventType The type of event.
    extProjectId A unique identifier for your project
    extLineItemId A unique identifier for your line item
    parentEventId The eventId of the LineItem:RepriceTriggered event
    resource.status The previous and new value of the status of Line Item
    createdAt Timestamp of when the event was created

    Billing & Invoicing

    Invoicing

    Invoicing is one of the core components of your project lifecycle. This section describes API resources that you can integrate with to be able to receive invoices after your project is done fielding responses.

    Get Invoice PDF

    Example Request

    curl "https://api.researchnow.com/sample/v1/projects/project001/invoices"
      -H "Authorization: Bearer <Access-Token>"
      -o "project001_invoice.pdf"
    

    Example Response(200):

    Invoice PDF will be downloaded in the current directory with the filename project001_invoice.pdf
    

    Example Response(400):

    {
        "data": null,
        "meta": null,
        "status": {
            "errors": [
                {
                    "code": "400",
                    "message": "project state not in INVOICED state"
                },
                {
                    "code": "INFO",
                    "message": "requestId: R5d4Hvgy"
                }
            ],
            "message": "bad request"
        }
    }
    

    Returns you the requested project invoice. You will be able to get the invoice only when the state of the project is INVOICED.

    HTTP Request

    GET /projects/{extProjectId}/invoices

    Response

    Returns the invoice PDF of the project as the filename mentioned in the request

    Reconciliation

    Create Reconciliation Request

    Example Request

    curl "https://api.researchnow.com/sample/v1/projects/project001/reconcile"
      -X POST \
      -H "Authorization: Bearer <Access-Token>" \
      -F "file=@/Users/researchnow/Documents/Data\ Quality\ Request.xlsx" \
      -F "message=Please reconcile these completes."
    

    Example Response(200):

    The excel sheet containing the Data Quality Request Template will be uploaded
    

    Example Response(400):

    {
        "data": null,
        "meta": null,
        "status": {
            "errors": [
                {
                    "code": "400",
                    "message": "project state not in CLOSED or INVOICED state"
                },
                {
                    "code": "INFO",
                    "message": "requestId: i2diZ+e4"
                }
            ],
            "message": "bad request"
        }
    }
    

    You can send us the rejected Ids via the API, or get in touch with your account manager for initiating a reconciliation request. Reconciliation can only begin if the project is in CLOSED or INVOICED state. Any adjustments, if applicable, will be handled by your account manager and we recommend that you follow up with them after putting the request.

    Please see the following link for the Data quality request template that needs to be sent for reconciliation: Data Quality Request Template.xlsx

    HTTP Request

    GET /projects/{extProjectId}/reconcile

    Data Endpoints

    Countries & Languages

    curl "https://api.researchnow.com/sample/v1/countries"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetCountries(nil)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetCountries(null);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    The above command returns JSON structured like this:

    {
      "data": [
        {
          "id": "GB",
          "isoCode": "GB",
          "countryName": "United Kingdom",
          "supportedLanguages": [
            {
              "id": "en_GB",
              "isoCode": "en_GB",
              "languageName": "English (UK)"
            }
          ]
        },
        {
          "id": "US",
          "isoCode": "US",
          "countryName": "United States of America",
          "supportedLanguages": [
            {
              "id": "en_US",
              "isoCode": "en_US",
              "languageName": "English (US)"
            },
            {
              "id": "es_US",
              "isoCode": "es_US",
              "languageName": "Spanish (US)"
            }
          ]
        },
        ...
      ]
    }
    

    Get the list of supported countries and languages in each country

    HTTPS Request

    GET /countries

    Response Parameters

    Parameter Description
    id Resource Id
    isoCode 2 Letter ISO Code of the country
    countryName Name of the country
    supportedLanguages List of supported languages in the country
    supportedLanguages[].id Language resource Id
    supportedLanguages[].isoCode 2 Letter ISO code of the locale
    supportedLanguages[].languageName Name of the language

    Attributes

    curl "https://api.researchnow.com/sample/v1/attributes/{countryCode}/{languageCode}"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetAttributes("US", "en", nil)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetAttributes("US", "en", null);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    The above command returns JSON structured like this:

    {
      "data": [
        {
          "id": "11",
          "name": "Gender",
          "text": "What is your gender?",
          "isAllowedInFilters": true,
          "isAllowedInQuotas": true,
          "type": "LIST",
          "options": [
            {
              "id": "1",
              "text": "Male"
            },
            {
              "id": "2",
              "text": "Female"
            }
          ]
        },
        {
          "id": "13",
          "name": "Age",
          "text": "What is your age?",
          "isAllowedInFilters": true,
          "isAllowedInQuotas": true,
          "type": "INTEGER_RANGE",
          "options": []
        },
        ...
      ]
    }
    

    Get the list of supported attributes for a country and language. This data is required to build up the Quota Plan.

    HTTPS Request

    GET /attributes/{countryCode}/{languageCode}

    Response Parameters

    Parameter Description
    id Attribute Id
    name Attribute name
    text Attribute Text
    isAllowedInFilters Whether Line Item filtering is allowed with the attribute. Please see Add Line Item
    isAllowedInQuotas Whether Line Item QuotaGroup allocations is allowed with the attribute. Please see Add Line Item
    type LIST - List would have options defined, INTEGER requires an integer value, INTEGER_RANGE requires a min and max value separated by a hyphen. e.g. "18-24", "25-35"
    options[].id Option Id, available if type is LIST
    options[].text Option text, available if type is LIST

    Categories

    Survey Topic

    curl "https://api.researchnow.com/sample/v1/categories/surveyTopics"
      -H "Authorization: Bearer <Access-Token>"
    
    client := samplify.NewClient("client_id", "username", "password")
    res, err := client.GetSurveyTopics(nil)
    if err != nil {
      // handle error
    }
    
    var client = new SamplifyClient("client_id", "username", "password", SamplifyEnv.UAT);
    try
    {
        var res = await client.GetSurveyTopics(null);
        if (res.HasError)
        {
            // handle API errors
        }
    }
    catch (Exception e)
    {
        //handle exceptions such as `ValidationException` and `SamplifyAuthenticationException`
    }
    

    The above command returns JSON structured like this:

    {
      "data": [
        {
          "topic": "AUTOMOTIVE",
          "description": "Automotive"
        },
        {
          "topic": "BEVERAGES_ALCOHOLIC",
          "description": "Beverages - Alcoholic"
        },
        {
          "topic": "BEVERAGES_NON_ALCOHOLIC",
          "description": "Beverages - Non Alcoholic"
        },
        {
          "topic": "BUSINESS",
          "description": "Business"
        },
        ...
      ]
    }
    

    Get the list of supported Survey Topics for a project. This data is required to setup a project.

    HTTPS Request

    GET /categories/surveyTopics

    Response Parameters

    Parameter Description
    topic Survey Topic Enum. You need to send the topic in Create Project
    description Survey Topic Description.

    Guidelines

    Survey Content

    At Dynata, we care deeply about our panelists experience, and a good survey design directly impacts panelists engagement. An engaged panelist will strive to provide the best responses, which means the data that you get is actual market insights. In order to maintain this experience, we will test your surveys to make sure they adhere to our survey content guidelines. Dynata reserves the right to reject your survey if it is found to be in breach of any of the below guidelines:

    Category Description
    Explicit Content Surveys should not contain any explicit/lewd content that might be offensive to panelists
    Under age surveys Surveys should not target panelists below 18 years old
    PII Collection Surveys should not ask any Personally Identifiable Information to our panelists
    Recruitment Surveys should not recruit Dynata panelists
    Survey Categories Surveys should be properly categorized with the most appropriate surveyTopic. Miscategorization can lead to rejection
    Device Friendliness Surveys should be device friendly. Mobile Targeted device will require mobile friendly surveys
    Survey Localization Surveys should be localized in the language you have mentioned during line item setup
    Survey Design Surveys should maintain a good design experience. Not too many grid questions, open ends, etc.

    If you are specifically looking to get insights on surveys that do not follow above guidelines, please get in touch with your account manager and they can help you get the project setup through our offline channel

    Quota Plan

    Restrictions

    When defining the quota plan for a line item, some restrictions apply:

    Nesting is allowed in any one quota group only

    Nesting is only allowed for any one quota group. This validation is in place, as targeting setup becomes complex with multiple nested quota groups.

    Targeting cannot span quota groups

    Targeting for Gender, Age Range, Income Range, etc, cannot span multiple quota groups. This is to ensure that quota groups are not not structured to exclude all respondents.

    E.g. Specifying Male in one quota group and Female in a different quota group would be invalid, since to be eligible to participate in the Survey, a panelist must match at least one quota in each quota group. Given that a respondent can't e.g. be both male and female, such a quota structure would not allow any respondent to participate.

    Options within a quota must be unique and not overlap

    Options defined within the quota of a quota group must be unique, and not overlap.

    E.g. Specifying age range targeting from 18-24, and 20-30 is invalid, since these options overlap and are not unique

    Count of allocation per quotaGroup needs to add up to the total count of line item

    Count of allocations specified for quotaCells of a quota group must add up to the total count of line item. This is necessary to make sure we have defined allocations for all the required completes.

    Please check attribute properties when setting up the quota plan

    Only Attributes that have isAllowedInFilters property as true can be used in Filters.

    Only Attributes that have isAllowedInQuotas property as true can be used in Quota Groups