NAV
python sdk python ruby shell

Surge API

Welcome to the Surge API! You can use the API to programmatically create projects and run tasks. All you need is your API key, and funds in your account if you want to have tasks completed by our workforce.

If you are using Python, we recommend using our Python SDK to access the API. It can be installed by running pip install surge-api. More details are available on the Python SDK Github page.

If you have any questions about the API or SDK, feel free to contact us at engineering@surgehq.ai.

Authentication

To authorize, use this code.

require 'httparty'

# For POST requests
HTTParty.post("{{API_ENDPOINT}}", 
  basic_auth: { username: "{{YOUR_API_KEY}}" },
  body: {
    ... # Parameters in the POST request
  }
)

# For GET requests
HTTParty.get("{{API_ENDPOINT}}", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

# For POST requests
requests.post("{{API_ENDPOINT}}", 
  auth = ("{{YOUR_API_KEY}}", ""),
  json = {
    ... # Parameters in the POST request
  }
)

# For GET requests
requests.get("{{API_ENDPOINT}}", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

# Or set the API key as an environment variable:
# export SURGE_API_KEY={{YOUR_API_KEY}}
# Note that the colon follows the API key and is not part of it.
curl {{API_ENDPOINT}} \
  -u {{YOUR_API_KEY}}:

Surge uses API keys to allow access to the API. You can find your API key in your profile.

Authentication is performed via HTTP Basic Auth. Your API key is your basic auth username, and you do not need to provide a password.

If you need to authenticate via bearer auth (e.g., for a cross-origin request), use -H "Authorization: {{YOUR_API_KEY}}:" instead of -u {{YOUR_API_KEY}}:.

Example

Let's walk through an example using Surge to categorize companies. If you'd like to run the example yourself, find your API key in your profile.

require 'httparty'

# First, we create a "categorize company" project.
response = HTTParty.post("https://app.surgehq.ai/api/projects", 
  basic_auth: { username: "DJ34KFX24M2G3JRHGXNZVCPE" },
  body: {
    name: "Categorize this company",
    payment_per_response: 0.1,
    questions: [
      {
        "text": "What is this company's website?"
      },
      {
        "text": "What category does this company belong to?",
        "options": ["Tech", "Sports", "Gaming"]
      }
    ]
  }
)

# Extract the project ID.
project_id = JSON.parse(response.body)["id"]

# Post a task to the API.
HTTParty.post("https://app.surgehq.ai/api/projects/#{project_id}/tasks",
  basic_auth: { username: "DJ34KFX24M2G3JRHGXNZVCPE" },
  body: {
    "fields": {
      "website": "google.com"
    }    
  }
)

# Retrieve the tasks and any responses.
response = HTTParty.get("https://app.surgehq.ai/api/projects/#{project_id}/tasks",
  basic_auth: { username: "DJ34KFX24M2G3JRHGXNZVCPE" }
)

JSON.parse(response.body).each do |task|
  puts task["responses"][0]["response_data"]
end
import requests

requests.post("https://app.surgehq.ai/api/projects", 
  auth = ("{{YOUR_API_KEY}}", ""),
  json = {
    "name": "Categorize this company",
    "payment_per_response": 0.1,
    "questions": [
      {
        "text": "What is this company's website?"
      },
      {
        "text": "What category does this company belong to?",
        "options": ["Tech", "Sports", "Gaming"]
      }
    ]
  }
)
import surge
from surge.questions import FreeResponseQuestion, MultipleChoiceQuestion
surge.api_key = "{{YOUR_API_KEY}}"

# Create questions to add to the project
free_response_q = FreeResponseQuestion(
    text="What is this company's website?",
    required=True
)

multiple_choice_q = MultipleChoiceQuestion(
    text="What category does this company belong to?",
    options=["Tech", "Sports", "Gaming"],
    required=False
)

project = surge.Project.create(
    name="Categorize this company",
    payment_per_response=0.1,
    questions=[free_response_q, multiple_choice_q])

Projects

Create a project

Definition

POST https://app.surgehq.ai/api/projects

Example Request

curl https://app.surgehq.ai/api/projects \
  -u {{YOUR_API_KEY}}: \
  -d name="Categorize this company" \
  -d payment_per_response=0.1 \
  -d questions=... (can't do this in curl)
require 'httparty'

HTTParty.post("https://app.surgehq.ai/api/projects", 
  basic_auth: { username: "{{YOUR_API_KEY}}" },
  body: {
    name: "Categorize this company",
    payment_per_response: 0.1,
    instructions: "You will be asked to categorize a company.",
    questions: [
      {
        "type": "free_response",
        "text": "What is this company's website?"
      },
      {
        "type": "multiple_choice",
        "text": "What category does this company belong to?",
        "options": ["Tech", "Sports", "Gaming"]
      },
      {
        "type": "checkbox",
        "text": "Check all the social media accounts this company has",
        "options": ["Facebook", "Twitter", "Pinterest", "Google+"]
      }
    ]
  }
)
import requests

requests.post("https://app.surgehq.ai/api/projects", 
  auth = ("{{YOUR_API_KEY}}", ""),
  json = {
    "name": "Categorize this company",
    "payment_per_response": 0.1,
    "instructions": "You will be asked to categorize a company.",
    "questions": [
      {
        "type": "free_response",
        "text": "What is this company's website?"
      },
      {
        "type": "multiple_choice",
        "text": "What category does this company belong to?",
        "options": ["Tech", "Sports", "Gaming"]
      },
      {
        "type": "checkbox",
        "text": "Check all the social media accounts this company has",
        "options": ["Facebook", "Twitter", "Pinterest", "Google+"]
      }
    ]
  }
)
import surge
from surge.questions import (FreeResponseQuestion, MultipleChoiceQuestion,
                             CheckboxQuestion)
surge.api_key = "{{YOUR_API_KEY}}"

# Create questions to add to the project
free_response_q = FreeResponseQuestion(
    text="What is this company's website?",
    required=True
)

multiple_choice_q = MultipleChoiceQuestion(
    text="What category does this company belong to?",
    options=["Tech", "Sports", "Gaming"],
    required=False
)

checkbox_q = CheckboxQuestion(
    text="Check all the social media accounts this company has",
    options=["Facebook", "Twitter", "Pinterest", "Google+"])

tree_selection_q = TreeSelectionQuestion(
    text="Select the company's industry",
    options=["Technology / Consumer", "Technology / Enterprise", "Entertainment / Sports", "Entertainment / Gaming"],
    descriptions=["Tooltip 1", "Tooltip 2", "Tooltip 3", "Tooltip 4"])

project = surge.Project.create(
    name="Categorize this company",
    payment_per_response=0.1,
    instructions="You will be asked to categorize a company.",
    questions=[free_response_q, multiple_choice_q, checkbox_q, tree_selection_q])

Example Response

Project({
  "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
  "name": "Categorize this company",
  "num_tasks": 0,
  "num_tasks_completed": 0,
  "num_workers_per_task": 1,
  "payment_per_response": 0.1,
  "status": "unlaunched"
})

Creates a project. It is also possible to create a project through the web UI (instead of the API), and you will still be able to use the API to post tasks to the project.

Parameters

Parameter Type Description
name string Required. Name to give your project.
private_workforce boolean Optional (default false). If true, the project won't be shown to the Surge workforce and will only be available to workers who receive the link to your task. If false,
payment_per_response float Optional, only required for tasks being sent to the Surge workforce. Amount in dollars to pay workers for each response. You will need enough funds in your account to pay for all of the responses required by the project before launching it.
instructions string Optional. Instructions shown to workers describing how they should complete the task.
fields_template string Optional. A template describing how fields are shown to workers working on the task. For example, if fields_template is <a href="{{url}}">{{company_name}}</a>, then workers will be shown a link to the company.
questions array Required. An array of question objects describing the questions to be answered. Each question object contains a text field (the text of the question), an optional options array (for multiple choice and checkbox questions, listing the answer options), a type field (one of free_response, multiple_choice, or checkbox), and a required boolean field (describing whether or not workers must answer the question). See the Question Types section for a list of available question types.
num_workers_per_task integer Optional (default 1). Number of workers who work on each task.
qualifications_required list[string] If you have created a custom qualification group, you can pass a list of qualifications workers must have to work on the project here. To find the qualification ID, you can go to the Qualifications tab, click on the qualification you are interested in, and take the ID from the URL.
callback_url string Optional. The callback URL is useful if you want to get notified each time an individual task has been annotated. If it is specified Surge will send a POST request to the callback_url with results each time an individual task is completed. This is an advanced feature and is not required in most cases.
tags array Optional. You can optionally pass an array of strings to tag your project with additional information, like a batch id for a particular dataset. When you retrieve the project later, you can access the tags in project.tags. Workers will not be able to see the tags.

Question Types

Surge provides a variety of inputs so you can create a labeling project without having to create your own interface, including multiple choice and checkbox selections, text inputs, name entity recognition tagging, file uploads, ranking, and more. Each question type and the setup parameters they take is listed below.

Multiple Choice

The worker is presented with a multiple choice question and can only select one answer. Descriptions is an optional argument where you can pass a list of tooltips that corresponds to your options.

Screenshot:

Multiple Choice Item

SDK Object: MultipleChoiceQuestion(text, options=[], descriptions=[], required=True, preexisting_annotations=None, require_tiebreaker=False))

Parameter Type Description
text string The text of the question being asked, e.g. "Is the sentiment of this text positive or negative?"
options List[string] A list of the options for the radios, e.g. ["Yes", "No"].
descriptions List[string] Tooltip text for the options. This should have the same length as the options.
required boolean Defaults to true. Whether or not workers must fill out this question before moving on to the next task.
preexisting_annotations string You can use preexisting annotations to prepopulate the radio selection with an option specified in the task data. The preexisting_annotations param should contain the task data key you are loading the default values from.
require_tiebreaker boolean If set to true, more workers will be assigned to this task if fewer than 50% agree on an answer. For example, imagine you are using two workers per task. If one selects Option A and the second one selections Option B a third will be assigned to the task to break the tie.

Checkbox

The worker is presented with a series of options and can check as many as they want.

Screenshot:

Checkbox Item

SDK Object: CheckboxQuestion(text, options, descriptions)

Parameter Type Description
text string The text of the question being asked, e.g. "Check all the apply."
options List[string] A list of the options for the checkboxes.
descriptions List[string] Tooltip text for the options. This should have the same length as the options.
required boolean Defaults to true. Whether or not workers must check at least one box before moving on to the next task.
preexisting_annotations string You can use pre existing annotations to prepopulate the checkboxes with options specified in the task data. The pre existing_annotations param should contain the task data key you are loading the default values from.
require_tiebreaker boolean If set to true, more workers will be assigned to this task if fewer than 50% agree on an answer. For example, imagine you are using two workers per task. If one selects Option A and the second one selections Option B a third will be assigned to the task to break the tie.

Text Tagging / Named Entity Recognition

The worker can tag spans of text in an NER-style tool.

Screenshot:

Text Tagging Item

SDK Object: TextTaggingQuestion(text, options)

Parameter Type Description
text string The text that needs to be tagged.
options List[string] A list of tags that can be used to tag spans of text, e.g. ["Person", "Place"].
preexisting_annotations string You can use pre existing annotations to prepopulate the named entity tagger. This must contain serialized JSON data in the same format outputted by the text tagging tool.
token_granularity boolean If set to true, spans will snap to the nearest word to prevent workers from accidentally tagging parts of words.
allow_relationship_tags boolean If true, enable relationship tagging.
allow_overlapping_tags boolean If true, allow multiple tags to be assigned to the same span of text.

Tree Selection

The worker chooses an option from a hierarchical selector.

Screenshot:

Tree Selection Item

SDK Object: TreeSelectionQuestion(text, options, required, descriptions)

Parameter Type Description
text string The text of the question being asked, e.g. "Which category does this example belong to?"
options List[string] A list of the options for the tree. Each level of hierarchy should be separate by a " / ". For example, one valid set of options would be ["1A / 2A", "1A / 2B", "1B / 2C", "1B / 2D"].
descriptions List[string] Tooltip text for the options. This should have the same length as the options. You can substitute in empty strings if one option doesn't have a tooltip.
preexisting_annotations string You can use preexisting annotations to prepopulate the selection with an option specified in the task data. The preexisting_annotations param should contain the task data key you are loading the default values from.
require_tiebreaker boolean If set to true, more workers will be assigned to this task if fewer than 50% agree on an answer. For example, imagine you are using two workers per task. If one selects Option A and the second one selections Option B a third will be assigned to the task to break the tie.

Text Area

For some projects, it's useful to show additional content to the workers beyond the fields template at the top of the page. The text area item allows you to display text or HTML content to the worker in between other questions. It doesn't take any input from the worker and isn't a question itself. The text argument contains the text or HTML you want to show.

Screenshot:

Text Area

SDK Object: TextArea(text)

Parameter Type Description
text string Text or HTML content to display.

File Upload

Add a file upload widget where workers can upload images, documents, or other files.

Screenshot:

File Upload

SDK Object: FileUpload(text)

Parameter Type Description
text string Text to display above the file upload widget.

Ranking

Create a ranking widget. Workers can drag and drop the option to specify their ranking.

Screenshot:

Ranking

SDK Object: RankingQuestion(text)

Parameter Type Description
text string Text to display above options to be ranked.
options List[string] A list of the options being ranked.

ChatBot

Allows the worker to chat with the bot via the specified API endpoint and rate their chat at the end of the conversation.

Screenshot:

ChatBot

SDK Object: ChatBot(text)

Retrieve a project

Definition

GET https://app.surgehq.ai/api/projects/{{PROJECT_ID}}

Example Request

require 'httparty'

HTTParty.get("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.get("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")
curl https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8 \
  -u {{YOUR_API_KEY}}:

Example Response

Project({
  "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
  "name": "Categorize this company",
  "num_tasks": 1000,
  "num_tasks_completed": 239,
  "num_workers_per_task": 1,
  "payment_per_response": 0.1,
  "status": "unlaunched"
})

Retrieves a specific project you have created.

Parameter Type Description
id string Unique identifier for project.
created_at DateTime When the project was created.
fields_template string A template describing how fields are shown to workers working on the task. For example, if fields_template is <a href="{{url}}">{{company_name}}</a>, then workers will be shown a link to the company.
instructions string Instructions shown to workers describing how they should complete the task.
name string Name of the project.
link_to_work_on_task string URL for working on the task. If you are using the private workforce option, this is the URL you will want to send to your workforce.
num_tasks integer Number of tasks in the project.
num_tasks_completed integer Number of completed tasks.
num_workers_per_task integer How many workers work on each task (i.e., how many responses per task).
payment_per_response float How much a worker is paid (in US dollars) for an individual response.
questions array An array of question objects describing the questions to be answered. Each question object contains a text field (the text of the question), an optional options array (for multiple choice and checkbox questions, listing the answer options), a type field (one of free_response, multiple_choice, or checkbox), and a required boolean field (describing whether or not workers must answer the question). See the Question Types section for a list of available question types.
status string One of in_progress, completed, canceled, or paused.
interrater_agreement Dictionary A dictionary mapping each question to the its interrater agreement score.
avg_gold_standard_score Float The average correctness of the project's gold standard responses, ranging from 0-100. For gold standards set multiple choice questions, this is the percent of workers who answered correctly. For checkbox questions, this is the proportion of checkboxes where the worker correctly checked it or left it unchecked. For text tagging questions this is the average of a similarity score between the gold standard tags and worker tags.

List all projects

Definition

GET https://app.surgehq.ai/api/projects
GET https://app.surgehq.ai/api/projects?page=n

Example Request

require 'httparty'

HTTParty.get("https://app.surgehq.ai/api/projects?page=2", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.get("https://app.surgehq.ai/api/projects", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

projects = surge.Project.list(page=1)
curl https://app.surgehq.ai/api/projects \
  -u {{YOUR_API_KEY}}:

Example Response

[
  Project({
    "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
    "name": "Categorize this company",
    "num_tasks": 1000,
    "num_tasks_completed": 239,
    "num_workers_per_task": 1,
    "payment_per_response": 0.1,
    "status": "unlaunched"
  }),
  Project({
    "id": "81533541-0359-4d4b-a545-af38a2cb3e8c",
    "name": "Label product images",
    "num_tasks": 5000,
    "num_tasks_completed": 4315,
    "num_workers_per_task": 1,
    "payment_per_response": 0.25,
    "status": "in_progress"
  })
]

Get a list of all the projects you have created. Returns a list of Project objects.

Parameters

Parameter Type Description
page integer Projects are returned in descending created_at order. Each page contains a maximum of 25 projects. Pages start at 1. (optional, default 1)

Launch a project

Definition

PUT https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/launch

Example Request

require 'httparty'

HTTParty.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/launch", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/launch", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")

project = project.launch()
curl https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/launch \
  -u {{YOUR_API_KEY}}: \
  -X PUT

Example Response

Project({
  "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
  "name": "Categorize this company",
  "num_tasks": 1000,
  "num_tasks_completed": 239,
  "num_workers_per_task": 1,
  "payment_per_response": 0.1,
  "status": "in_progress"
}

Launches a project. If you are sending your project to the Surge workforce, you will need to have enough funds in your account to pay for the project before launching. You can add funds on this page.

Pause a project

Definition

PUT https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/pause

Example Request

require 'httparty'

HTTParty.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/pause", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/pause", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")

project = project.pause()
curl https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/pause \
  -u {{YOUR_API_KEY}}: \
  -X PUT

Example Response

Project({
  "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
  "name": "Categorize this company",
  "num_tasks": 1000,
  "num_tasks_completed": 239,
  "num_workers_per_task": 1,
  "payment_per_response": 0.1,
  "status": "paused"
}

Pauses a project. Tasks added to the project will not be worked on until you resume the project.

Resume a project

Definition

PUT https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/resume

Example Request

require 'httparty'

HTTParty.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/resume", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/resume", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")

project = project.resume()
curl https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/resume \
  -u {{YOUR_API_KEY}}: \
  -X PUT

Example Response

Project({
  "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
  "name": "Categorize this company",
  "num_tasks": 1000,
  "num_tasks_completed": 239,
  "num_workers_per_task": 1,
  "payment_per_response": 0.1,
  "status": "in_progress"
})

Resumes a paused project.

Cancel a project

Definition

PUT https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/cancel

Example Request

require 'httparty'

HTTParty.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/cancel", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.put("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/cancel", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")

project = project.cancel()
curl https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/cancel \ 
  -u {{YOUR_API_KEY}}: \
  -X PUT

Example Response

Project({
  "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
  "name": "Categorize this company",
  "num_tasks": 1000,
  "num_tasks_completed": 239,
  "num_workers_per_task": 1,
  "payment_per_response": 0.1,
  "status": "canceled"
})

Cancels a project.

Update a project

Definition

POST https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/update

Example Request

require 'httparty'

HTTParty.put("https://app.surgehq.ai/api/17e323f1-f7e4-427c-a2d5-456743aba8/update", 
  basic_auth: { username: "{{YOUR_API_KEY}}" },
  body: {
    name: "New Project Name",
    instructions: "Some updated instructions: You will be asked to categorize a company."
  }
)
import requests

requests.put("https://app.surgehq.ai/api/17e323f1-f7e4-427c-a2d5-456743aba8/update", 
  auth = ("{{YOUR_API_KEY}}", ""),
  data = {
    "name": "New Project Name",
    "instructions": "Some updated instructions: You will be asked to categorize a company."
  }
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")

project = project.update(name='New Project Name', instructions='Some updated instructions: You will be asked to categorize a company.')
curl https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8 \
  -u {{YOUR_API_KEY}}: \
  -X PUT
  -d name="New Project Name" \
  -d instructions="Some updated instructions: You will be asked to categorize a company." \

Example Response

Project({
  "id": "17e323f1-f7e4-427c-a2d5-456743aba8",
  "name": "New Project Name",
  "num_tasks": 1000,
  "num_tasks_completed": 239,
  "num_workers_per_task": 1,
  "payment_per_response": 0.1,
  "status": "in_progress"
})

Updates project properties. You can just pass the new values for any parameters you want to update and leave the rest off.

Parameters that can be updated

Parameter Type Description
name string Name to give your project.
payment_per_response float Amount in dollars to pay workers for each response. You will need enough funds in your account to pay for all of the responses required by the project before launching it.
instructions string Instructions shown to workers describing how they should complete the task.
fields_template string A template describing how fields are shown to workers working on the task. For example, if fields_template is <a href="{{url}}">{{company_name}}</a>, then workers will be shown a link to the company.
num_workers_per_task integer Number of workers who work on each task.

Tasks

The task object

Example Response

Task({
  "id": "38da6bc5-a644-41b9-a964-4678bc7375c6",
  "project_id": "b31ede78-afdf-4938-b775-8813453c7fc5",
  "created_at": "2016-11-01T18:56:56.000Z",
  "is_complete": true,

  "fields": {
    "company": "Surge",
    "city": "San Francisco",
    "state": "CA"
  },

  "responses": [
    TaskResponse({
      "id": "1befb37b-8e4f-42b6-8a61-2c946ad4b5ce",
      "data": {
        "website": "https://app.surgehq.ai",
        "category": "Technology"
      },
      "time_spent_in_secs": 2,
      "completed_at": "2016-11-01T23:29:17.971Z",
      "worker_id": "P94T3ATCZX4X"
    })
  ]
})
Parameter Type Description
id string Unique identifier for the task.
created_at DateTime When the task was created.
project_id string ID of the project that this task belongs to.
is_complete boolean Whether or not this task has received the desired number of responses (equal to the project's num_workers_per_task field).
fields dictionary A dictionary of named fields that get shown (according to the project template) to workers when working on the task.
responses array An array of TaskResponses to the task. Each TaskResponse object contains an id, time_spent_in_secs field, completed_at field, worker_id field, and a data dictionary that maps questions to their answers.

Create tasks

Definition

POST https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/tasks

Example Request

require 'httparty'

HTTParty.post("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks", 
  basic_auth: { username: "{{YOUR_API_KEY}}" },
  body: {
    "fields": {
      "company": "Surge",
      "city": "San Francisco",
      "state": "CA"
    }    
  }
)
import requests

requests.post("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks", 
  auth = ("{{YOUR_API_KEY}}", ""),
  json = {
    "fields": {
      "company": "Surge",
      "city": "San Francisco",
      "state": "CA"
    }
  }
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")

tasks = project.create_tasks([{
    "company": "Surge",
    "city": "San Francisco",
    "state": "CA"
}], launch=False)
curl https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks \
  -u {{YOUR_API_KEY}}: \
  -d data=... (can't do this in curl)

Example Response

Task({
  "id": "38da6bc5-a644-41b9-a964-4678bc7375c6",
  "project_id": "b31ede78-afdf-4938-b775-8813453c7fc5",
  "created_at": "2016-11-01T18:56:56.000Z",
  "is_complete": false,

  "fields": {
    "company": "Surge",
    "city": "San Francisco",
    "state": "CA"
  },

  "responses": []
})

Creates a task. If you are using the Python SDK, you can also create tasks in bulk using create_tasks. If you are using the Python SDK, you also have the option of passing launch=True as a keyword argument then the project will also be launched immediately after task creation.

Parameters

Parameter Type Description
fields dictionary A dictionary of named fields that get shown (according to the project template) to workers when working on the task. (required)
launch boolean Python SDK only. If true, launch the project immediately after the tasks are created.

Create a task with an associated task response

Creates a task, and creates a response to that task.

Whenever a task is created, the project is automatically launched if it is not already in progress.

Definition

POST https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/tasks/create_with_response

Example Request

require 'httparty'

HTTParty.post("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks/create_with_response", 
  basic_auth: { username: "{{YOUR_API_KEY}}" },
  body: {
    "task": {
      "fields": {
        "company": "Surge",
        "city": "San Francisco",
        "state": "CA"
      }
    },
    "response": {
      "answers": ["Good", ["Machine Learning", "Tech Sector"], ""],
      "worker_email": "aidatatrainer.EUID@gmail.com"
    }  
  }
)
import requests

requests.post("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks/create_with_response", 
  auth = ("{{YOUR_API_KEY}}", ""),
  json = {
    "task": {
      "fields": {
        "company": "Surge",
        "city": "San Francisco",
        "state": "CA"
      }
    },
    "response": {
      "answers": ["Good", ["Machine Learning", "Tech Sector"], ""],
      "worker_email": "aidatatrainer.EUID@gmail.com"
    }  
  }
)
Not currently supported for python sdk.
curl --location --request POST 'localhost:3000/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks/create_with_response' \
  -u {{YOUR_API_KEY}}: \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "task": {
      "fields": {
        "company": "Surge",
        "city": "San Francisco",
        "state": "CA"
      }
    },
    "response": {
      "answers": ["Good", ["Machine Learning", "Tech Sector"], ""],
      "worker_email": "aidatatrainer.EUID@gmail.com"
    }  
  }'

Example Response

Task({
  "id": "38da6bc5-a644-41b9-a964-4678bc7375c6",
  "project_id": "b31ede78-afdf-4938-b775-8813453c7fc5",
  "created_at": "2016-11-01T18:56:56.000Z",
  "is_complete": false,

  "fields": {
    "company": "Surge",
    "city": "San Francisco",
    "state": "CA"
  },

  "responses": [
    TaskResponse({
      "id": "1befb37b-8e4f-42b6-8a61-2c946ad4b5ce",
      "data": {
        "How is the company?": "Good",
        "Select appropriate checkboxes": ["Machine Learning", "Tech Sector"],
        "Optional comments": null
      },
      "time_spent_in_secs": 2,
      "completed_at": "2016-11-01T23:29:17.971Z",
      "worker_id": "EUID"
    })
  ]
})

Parameters

Parameter Type Description
task dictionary A dictionary of parameters used to create the task. Acceptable key-value pairs for this dictionary are described as "task parameters" below. (required)
response dictionary A dictionary of parameters used to create the response to the task. Acceptable key-value pairs for this dictionary are described as "response parameters" below. (required)

Task parameters

Parameter Type Description
fields dictionary A dictionary of named fields that get shown (according to the project template) to workers when working on the task. (required)

Response parameters

Parameter Type Description
answers array An array of objects of length equal to the number of questions. For example, if there are two multiple choice questions and one checkbox question for a project, the answers array should contain three items. If there's a question the worker hasn't answered, you can leave the answer blank by passing an empty string. For multiple choice questions, the text of the selected option should be provided. For checkbox questions, an array of the text of selected options should be provided.
worker_email string The email of the worker who has completed the task response.

List all tasks

Definition

GET https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/tasks
GET https://app.surgehq.ai/api/projects/{{PROJECT_ID}}/tasks?page=n

Example Request

require 'httparty'

HTTParty.get("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.get("https://app.surgehq.ai/api/projects/17e323f1-f7e4-427c-a2d5-456743aba8/tasks", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

project = surge.Project.retrieve("17e323f1-f7e4-427c-a2d5-456743aba8")

tasks = project.list_tasks(page=1)
curl https://app.surgehq.ai/api/projects/b31ede78-afdf-4938-b775-8813453c7fc5/tasks \
  -u {{YOUR_API_KEY}}: \
  ...

Example Response

[
  Task({
    "id": "38da6bc5-a644-41b9-a964-4678bc7375c6",
    "project_id": "b31ede78-afdf-4938-b775-8813453c7fc5",
    "created_at": "2016-11-01T18:56:56.000Z",
    "is_complete": true,

    "fields": {
      "company": "Surge",
      "city": "San Francisco",
      "state": "CA"
    },

    "responses": [
      TaskResponse({
        "id": "1befb37b-8e4f-42b6-8a61-2c946ad4b5ce",
        "data": {
          "website": "https://app.surgehq.ai",
          "category": "Technology"
        },
        "time_spent_in_secs": 2,
        "completed_at": "2016-11-01T23:29:17.971Z",
        "worker_id": "P94T3ATCZX4X"
      })
    ]
  }),
  Task({
    "id": "dd66e80a-88b3-4c4f-9efc-2aca8eed73db",
    "project_id": "b31ede78-afdf-4938-b775-8813453c7fc5",
    "created_at": "2016-11-01T23:23:26.016Z",
    "is_complete": true,

    "fields": {
      "company": "Google",
      "city": "Mountain View",
      "state": "CA"
    },

    "responses": [
      TaskResponse({
        "id": "cc9f4263-1d0f-4730-a97e-199851b6ade5",
        "data": {
          "website": "https://www.google.com",
          "category": "Technology"
        },
        "time_spent_in_secs": 3,
        "completed_at": "2016-11-01T23:22:19.124Z",
        "worker_id": "P94T3ATCZX4X"
      })
    ]
  })
]

Lists all tasks belonging to a project.

Query Parameters

Parameters

Parameter Type Description
page integer Tasks are returned in ascending created_at order. Each page contains a maximum of 25 tasks. Pages start at 1. (optional, default 1)

Retrieve a task

Definition

GET https://app.surgehq.ai/api/tasks/{{TASK_ID}}

Example Request

require 'httparty'

HTTParty.get("https://app.surgehq.ai/api/tasks/38da6bc5-a644-41b9-a964-4678bc7375c6", 
  basic_auth: { username: "{{YOUR_API_KEY}}" }
)
import requests

requests.get("https://app.surgehq.ai/api/tasks/38da6bc5-a644-41b9-a964-4678bc7375c6", 
  auth = ("{{YOUR_API_KEY}}", "")
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

task = surge.Task.retrieve(task_id = "eaa44510-c8f6-4480-b746-28a6c8defd4c")
curl https://app.surgehq.ai/api/tasks/38da6bc5-a644-41b9-a964-4678bc7375c6 \
  -u {{YOUR_API_KEY}}:

Example Response

Task({
  "id": "38da6bc5-a644-41b9-a964-4678bc7375c6",
  "project_id": "b31ede78-afdf-4938-b775-8813453c7fc5",
  "created_at": "2016-11-01T18:56:56.000Z",
  "is_complete": true,

  "fields": {
    "company": "Surge",
    "city": "San Francisco",
    "state": "CA"
  },

  "responses": [
    TaskResponse({
      "id": "1befb37b-8e4f-42b6-8a61-2c946ad4b5ce",
      "data": {
        "website": "https://app.surgehq.ai",
        "category": "Technology"
      },
      "time_spent_in_secs": 2,
      "completed_at": "2016-11-01T23:29:17.971Z",
      "worker_id": "P94T3ATCZX4X"
    })
  ]
})

Retrieves a specific task you have created.

Set a gold standard answer

Definition

POST https://app.surgehq.ai/api/tasks/{{TASK_ID}}/gold-standards

Example Request

require 'httparty'

HTTParty.post("https://app.surgehq.ai/api/tasks/38da6bc5-a644-41b9-a964-4678bc7375c6/gold-standards", 
  basic_auth: { username: "{{YOUR_API_KEY}}" },
    body: {
    "answers": [
      "https://surgehq.ai",
      'Tech',
      ['Twitter']
    ]    
  }
)

import requests

requests.post("https://app.surgehq.ai/api/tasks/38da6bc5-a644-41b9-a964-4678bc7375c6/gold-standards", 
  auth = ("{{YOUR_API_KEY}}", ""),
  json = {
    "answers": [
      "https://surgehq.ai",
      'Tech',
      ['Twitter']
    ],
    "explanations": [
      "",
      "Surge AI provides a platform for viewing and processing data, so it is considered a technology company",
      ""
    ]
  }
)
import surge
surge.api_key = "{{YOUR_API_KEY}}"

task = surge.Task.retrieve(task_id = "eaa44510-c8f6-4480-b746-28a6c8defd4c")
task.set_gold_standard(['https://surgehq.ai', 'Tech', ['Twitter']], explanations=["", "Surge AI provides a platform for viewing and processing data, so it is considered a technology company", ""])
curl https://app.surgehq.ai/api/tasks/38da6bc5-a644-41b9-a964-4678bc7375c6/gold-standards \
  -u {{YOUR_API_KEY}}
  -d data=... (can't do this in curl)

Example Response

Task({
  "id": "38da6bc5-a644-41b9-a964-4678bc7375c6",
  "project_id": "b31ede78-afdf-4938-b775-8813453c7fc5",
  "created_at": "2016-11-01T18:56:56.000Z",
  "is_complete": false,

  "fields": {
    "company": "Surge",
    "city": "San Francisco",
    "state": "CA"
  },
  "gold_standard_data": "{'ner': {},'multiple_choice': {'b6337c97-6498-4c8c-a9ea-fcdc45782067': '3366ef4e-fe7f-4606-92bf-fba9a60a3d19'},'checkbox': {'f3feb6b0-daf9-42e3-9154-fc66fe10802d': ['44f050e2-e936-4241-8a1b-991bdb64a53e']},'free_response': {'85470cbd-8309-42ab-be70-500eb644736d': 'https://surgehq.ai'}}"
})

Gold standards are used to assess worker quality. After a gold standard answer is uploaded, every single worker will be given that piece of data so they can all be evaluated based on their performance. The average correctness across all gold standards in a project are in the gold_standard_score field, and you can see additional analytics on the site, including how each worker is performing on gold standards and aggregated stats indicating which gold standards are answered incorrectly most often.

Parameters

Parameter Type Description
answers List[String] or None A list of the ground truth answers for this task, one for each question in the project. If you don't want to set an answer for one of the questions, you can leave it blank by passing an empty string. For example, if you wanted to modify the example on the right to only set the company categorization multiple choice question as a gold standard then you could set answers to ['', 'Tech', ''].
is_gold_standard boolean This param indicates whether this task is a gold standard. You can toggle gold standards on or off without modifying the answers by setting this value to true or false and omitting the answers array.
explanations List[String] or None A list of explanations (one per question) for the gold standard answers, typically used to help train workers by explaining the reasoning behind each answer. Workers will still be tested on gold standards that include explanations, but whenver they answer incorrectly they will be show an explanation and prompted to fix their answer. If you don't want to set an explanation for one of the questions, you can leave it blank by passing an empty string.

Task Responses

The TaskResponse object

Example Response

TaskResponse({
  "id": "1befb37b-8e4f-42b6-8a61-2c946ad4b5ce",
  "data": {
    "website": "https://app.surgehq.ai",
    "category": "Technology"
  },
  "time_spent_in_secs": 2,
  "completed_at": "2016-11-01T23:29:17.971Z",
  "worker_id": "P94T3ATCZX4X"
})
Parameter Type Description
id string A unique identifier for the task response.
data dictionary A dictionary that maps each question to the worker's response.
time_spent_in_secs int Time (in seconds) that the worker spent to complete this task response.
completed_at string Timestamp of the response completion.
worker_id string ID of the worker that completed this task response.

Reports

Reports exist to fetch the responses created by workers for your project. They are generated asynchronously so there is one call to request the creation of a report (request) another to poll the status of the report generation (status). Please poll no more frequently than every second. When the report has been created, the response will include a signed URL to retrieve it.

Request creation of report

Parameters

Parameter Type Description
project_id string A unique identifier for the project.
type string One of the report types detailed below.

Report types:

Type Explanation
export_json A JSON export of the data.
export_json_aggregated As above but aggregated by task.
export_csv A CSV export of the data.
export_csv_aggregated As above but aggregated by task.
export_csv_flattened As above however aggregation is to a single row.

Note that aggregation is by task which only makes sense when the project has been created with multiple workers for a task. If there is only one worker per task, the data is the same between aggregated and non-aggregated.

Response

Creating

{
  status: "CREATING"
  job_id: ...
}

Ready

{
  status: "READY",
  url: ...,
  expires_in_seconds: ...
}

Example

import surge
surge.api_key = "{{YOUR_API_KEY}}"

response = surge.Report.request(project_id="e6c9068c-2633-4d04-bf88-11e1d7c5cea9", type="export_json")
print(response.print_attrs())

Check the status of a requested report

Parameters

Parameter Type Description
project_id string A unique identifier for the project.
job_id string The report creation job id obtained by calling status.

Response

In progress

{
  status: "IN_PROGRESS"
}

Completed

{
  status: "COMPLETED",
  url: ...,
  expires_in_seconds: ...
}

Retrying

{
  status: "RETRYING",
  job_id: ...
}

Error

{
  status: "ERROR",
  type: ...
}

Example

import surge
surge.api_key = "{{YOUR_API_KEY}}"

response = surge.Report.status(project_id="e6c9068c-2633-4d04-bf88-11e1d7c5cea9", job_id="bf00f584c382a705ddd14a85")
print(response.print_attrs())

Special Note: Compression

The URL to the report has a filename that ends with .json.gz to indicate the file is compressed with gzip. Please be sure to decompress the file before attempting to read it as JSON.

Toxicity Model

Get the toxicity score for a piece of text.

Parameter Type Description
text string The text you want a toxicity score for. The score returned will be between 0 and 1 and indicates the probability the given text is toxic.

Definition

POST https://app.surgehq.ai/api/toxicity_score

Example Request

require 'httparty'

HTTParty.post("https://app.surgehq.ai/api/toxicity_score", 
  basic_auth: { username: "{{YOUR_API_KEY}}" },
    body: {
    "text": "Thanks for your reply!"  
  }
)

import requests

requests.post("https://app.surgehq.ai/api/toxicity_score", 
  auth = ("{{YOUR_API_KEY}}", ""),
  json = {
    "text": "Thanks for your reply!"
  }
)
# The toxicity endpoint is not available in the SDK right now, please see the Python example.
curl https://app.surgehq.ai/api/toxicity_score \
  -u {{YOUR_API_KEY}}
  -d data=... (can't do this in curl)

Example Response

{"label": "p_toxic", "value": 0.006962232757359743}