The CoderPad Interview API

CoderPad provides a simple API for programmatically creating and managing interview pads. You can use the API to integrate these pads with your internal interview scheduling platform or to get a text dump of an interview after the fact.

CoderPad provides a standard REST API that returns results in JSON format.

Table Of Contents

  1. Authentication
  2. Errors
  3. The Pad Resource
  4. The Pad Environment Resource
  5. The Question Resource
  6. The Quota Resource
  7. The Organization Resource
  8. Appendix

Authentication

The API uses a simple HTTP Authorization header to authenticate you. If you visit your settings page, you’ll see your API key (this one is fake):

8af9a3412559d803707937250dc1569d

You can then make requests against the API endpoint like so:

curl -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/pads

Errors

The API will always return a top-level JSON object, along with a status code to indicate success or failure. When successful, the API will return an HTTP 200, as well as { status: "OK" }.

When calls are unsuccessful, they return an appropriate HTTP code, as well as something like

{
  "status": "ERROR",
  "message": "Invalid API key"
}

The following is a table of HTTP codes from errors that you can expect to see:

HTTP Code Message Description
200 Everything’s good!
400 Bad Request You sent a malformed request, like a programming language we don’t yet support.
401 Invalid API key Your API key wasn’t tied to a valid account.
403 Forbidden You don’t have permission to access that resource.
404 Resource not found We couldn’t find that resource for you… It probably doesn’t exist.
429 Over quota You’ve exceeded the number of pads your plan allows in a month. Upgrade your plan or shoot me an email!

The Pad Resource

Currently, the Interview API supports various operations on the pad endpoint: https://app.coderpad.io/api/pads. You can list pads, create pads, inspect a pad, or modify (in a limited fashion) existing pads.

GET /api/pads/:id (show)

Returns detail about a particular pad. Doing a straightforward curl like so:

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/pads/DM32JWG2

yields:

{
  status: "OK",
  id: "DM32JWG2",
  title: "Ruby Test",
  owner_email: "[email protected]",
  language: "ruby",
  participants: [
    "vincent",
    "Guest 405"
  ],
  contents: "5.times do\n  puts 'Hello, World!'\nend\n",
  notes: "Greg was a *very* gregarious candidate, whom..."
  events: "https://app.coderpad.io/api/pads/DM32JWG2/events",
  private: false,
  execution_enabled: true,
  created_at: "2014-11-14T03:02:45Z",
  updated_at: "2014-11-14T03:06:39Z",
  ended_at:   "2014-11-14T03:06:39Z",
  url: "https://coderpad.io/DM32JWG2",
  playback: "https://coderpad.io/DM32JWG2/playback",
  history: "https://coderpad.firebaseio.com/DM32JWG2/history.json",
  drawing: "https://storage.googleapis.com/..."
}

Fields returned:

Field Description
id Primary key for the object. Use this to query or modify this resource later.
title User-assigned title of the pad.
owner_email Email address of the owner of the pad. Will usually just be your email!
language Chosen language for the pad. One of a set list.
participants Array of strings of the self-reported names of the participants.
contents Latest contents of the pad editor. Updates in real-time. For pads that support multiple environments, this will be nil, and you can get the contents for each environment at the pad_environments endpoint.
notes Markdown-formatted notes taken by the interviewer.
events A link to an API endpoint containing a log of events created by users during the pad session. See below.
private Whether the pad is viewable by guests. Private pads will essentially 404 unless you are authorized to view the pad. Defaults to false.
execution_enabled Whether to allow running code in this pad. When set to false, this hides the right-hand side of the pad interface. Defaults to true.
created_at When the pad was created, in UTC ISO 8601, like 2015-01-30T00:22:55.520Z.
updated_at Similarly, when the pad was last updated.
ended_at The time when the interview was ended. null if it has not ended yet.
url Convenience field to link human users to the editing interface for this pad.
playback Convenience field to link human users to the playback interface for this pad.
history A URL where you can request the entire edit history of the pad in JSON form. For advanced users only.
drawing A URL where you can download the final state of a drawing made with Drawing Mode. These URLs are signed URLs that are valid for 5 minutes, after which you will need to make another request to our API to get a fresh signed URL.
pad_environment_ids An array of IDs which can be used to fetch the environment details from the pad_environments endpoint. See below.

All values returned by show are real-time as of the moment you request them.

GET /api/pads/:id/events

Returns detail about important events that transpired throughout the lifetime of the pad. It is represented as an array of objects with the following fields:

Field Description
message The human-readable string version of the event.
kind Can be one of:
  • joined: when a user browses to a pad
  • left: when a user closes the browser tab
  • ran: when a user executes code
  • enabled: when the pad owner enables code execution
  • disabled: when the pad owner disables code execution
  • ended: when the pad owner ends the interview
metadata Additional information associated with the event. In the case of a ran event, this will be the programming language run, for joined this can be invisible if a user joins in spectator mode.
user_name Name of the user performing the event, will always be present.
user_email If the user is logged in, this will be their email at the time of the event.
created_at When the event occurred.

This endpoint supports sorting and pagination similar to the /api/pads/ endpoint below.

GET /api/pads (index)

Fetch a list of all of your pads. Returns everything that an individual show request does. The only caveat is that the values of fields in the index view are not guaranteed to be 100% real-time. Generally, they should be no more than a minute behind, but if you absolutely require the latest value in a pad, please use the individual show endpoint.

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/pads?sort=updated_at,desc

index takes an optional sort parameter, which allows you to sort by either the created_at or updated_at fields on your pads. Adding a comma will allow you to change the sort direction, which is desc by default. For example, to sort your pads by updated_at from oldest to newest, specify updated_at,asc.

If no sort parameter is provided, created_at,desc is assumed.

The method also returns paginated results - no more than 50 per request. If you want more, follow the next_page or prev_page urls if present. The API also returns a total count to give you a sense of how many pads you have created.

{
  "status": "OK",
  "pads": [
    // ... your pads, with the same data format as in `show`
  ],
  "next_page": "https://app.coderpad.io/api/pads?sort=updated_at,desc&page=2",
  "total": 420
}

POST /api/pads (create)

Create a new pad. You can set some initial conditions as well.

curl \
  --data title="Rob Zombie's Interview" \
  --data language="ruby" \
  --data contents="print 'Hello, World'" \
  --data notes="Your private notes" \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/pads

returns

{
  "status": "OK",
  "id": "AFQ2K9A3",
  "title": "Rob Zombie's Interview",
  "owner_email": "[email protected]",
  "language": "ruby",
  "participants": ["vincent"],
  "contents": "print 'Hello, World'",
  "notes": "Your private notes",
  "events": "https://app.coderpad.io/api/pads/AFQ2K9A3/events",
  "private": false,
  "execution_enabled": true,
  "created_at": "2014-11-14T03:02:45Z",
  "updated_at": "2014-11-14T03:02:45Z",
  "ended_at": null,
  "url": "https://coderpad.io/AFQ2K9A3",
  "playback": "https://coderpad.io/AFQ2K9A3/playback",
  "history": "https://coderpad.firebaseio.com/AFQ2K9A3/history.json",
  "drawing": null
}

The available parameters you have to configure are detailed below:

Parameter Values
title Defaults to “Untitled Pad [ID]”.
language Defaults to the account default language, which in turn defaults to plaintext.
contents Initial contents of pad. Defaults to the example code for the language. Note: If you set contents, then you can’t set a question_id or the API will return an error.
question_id Question to associate with this pad. When you set this, it behaves similarly as if you created a pad from a question on the website: the question language becomes the new pad’s language, and question contents become the pad’s contents. Note: If you set question_id, then you can’t set contents or the API will return an error.
notes Any contents you would like to write to the Private Interviewer Notes in a pad.
private Defaults to the account default privacy setting, which in turn defaults to false.
execution_enabled Defaults to the account default execution setting, which in turn defaults to true.
user_email The email of the user to set as the owner of this pad, e.g. "[email protected]". This parameter can only be set by owners of the organization. This will also create a user account if necessary, as long as the email is a valid one for your organization.

This method can return a quota exceeded error if you are over your used pad limit for the month.

PUT /api/pads/:id (update)

Modifies an existing pad. You can specify any of the valid parameters to create.

You may also use this endpoint to end the interview, by setting the ended attribute to true, or delete the interview, by setting the deleted attribute to true. Values other than true will be ignored.

curl \
  -X PUT --data title="Interview with Greg" \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/pads/AFQ2K9A3

Please note that resetting contents in the middle of an ongoing interview session will probably break something. It will also destroy the history for that pad. Use with caution.

The Pad Environment Resource

GET /api/pad_environments/:id (show)

Returns detail about a particular pad environment. Doing a straightforward curl like so:

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/pad_environments/42

yields:

{
  "status": "OK",
  "id": 1,
  "pad_id": 3,
  "question_id": null,
  "example_question_id": null,
  "language": "ruby",
  "file_contents": [
    {
      "path": "coderpad/main.rb",
      "contents": "5.times do\n  puts 'Hello, World!'\nend\n"
    }
  ],
  "created_at": "2022-09-12T13:49:45.390-07:00",
  "updated_at": "2022-09-12T13:50:42.058-07:00"
}

Fields returned:

Field Description
id Primary key for the object. Use this to query or modify this resource later.
pad_id The pad this environment belongs to.
question_id If this is a question environment, this is the identifier for the question, otherwise null.
example_question_id If this is ???, this is the identifier for the example question, otherwise null.
language Chosen language for the pad environment. One of a set list.
file_contents Latest contents of the pad editor. Updates in real-time. For pads that support multiple environments, this will be nil, and you can get the contents for each environment at the pad_environments endpoint. See below.
created_at When the environment was created, in UTC ISO 8601, like 2015-01-30T00:22:55.520Z.
updated_at Similarly, when the environment was last updated.

The file_contents field contains information about the files associated with the environment. It is represented as an array of objects with the following fields:

Field Description
path The path to the file.
contents Initial contents of the file. Defaults to the example code for the language/file combination.

All values returned by show are real-time as of the moment you request them.

The Question Resource

The Interview API supports most operations on the questions endpoint: https://app.coderpad.io/api/questions. You can list questions, create questions, view questions, modify existing questions, or delete existing questions.

GET /api/questions/:id (show)

Returns details about a particular question. You can view questions visible to you, which includes your own questions as well as colleagues’ questions where shared is set to true. If you’re an organization owner, you can view all questions in the organization.

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/questions/42

yields:

{
  "status": "OK",
  "id": 42,
  "title": "Are fruits tomatoes?",
  "author_name": "Molly Macadamia",
  "owner_email": "[email protected]",
  "language": "postgresql",
  "description": "Use SQL magic to discover the answer.",
  "contents": "SELECT * FROM fruits;\n",
  "shared": true,
  "used": 0,
  "created_at": "2019-01-25T02:07:12Z",
  "updated_at": "2019-01-25T02:07:12Z"
}

Fields returned:

Field Description
id Primary key for the object. Use this to query or modify this resource later.
title User-assigned title of the question.
author_name Name of the person who authored this question. This is the same person as the owner referenced by owner_email.
owner_email Email address of the person who owns the question.
language Chosen language for the question. One of a set list.
description Notes for yourself (or colleagues) on what this question is about, and what good and bad answers might look like.
contents User-assigned question contents. This text is inserted into your interview session if you choose to use this question.
shared A boolean specifying whether this question is shared with the user’s organization. Defaults to true.
used A counter counting the number of times this question was used to create pads.
created_at The time when the question was created, in UTC ISO 8601, like 2019-01-30T00:22:55.520Z.
updated_at Similarly, the time when the question was last updated.

GET /api/questions (index)

Fetch a list of all of your questions. Returns all fields that an individual show request does.

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/questions?sort=updated_at,desc

index takes an optional sort parameter, which allows you to sort by either the created_at or updated_at fields on the questions. Adding a comma will allow you to change the sort direction, which is desc by default. For example, to sort your questions by updated_at from oldest to newest, specify updated_at,asc.

If no sort parameter is provided, created_at,desc is assumed.

The method also returns paginated results - no more than 50 per request. If you want more, follow the next_page or prev_page urls if present. The API also returns a total count to give you a sense of how many questions exist.

{
  "status": "OK",
  "questions": [
    // ... your questions, with the same data format as in `show`
  ],
  "next_page": "https://app.coderpad.io/api/question?sort=updated_at,desc&page=2",
  "total": 420
}

POST /api/questions (create)

Create a new question.

curl \
  --data title="Are avocados fruity?" \
  --data description="Fruit puzzler round 2" \
  --data language="ruby" \
  --data contents="def is_fruity?(thing);\n  end\n" \
  --data solution="This is the solution" \
  --data candidate_instructions="[{'instructions': 'Implement the is_fruity method'}]" \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/questions

returns the question just created:

{
  "status": "OK",
  "id": 7,
  "title": "Are avocados fruity?",
  "owner_email": "[email protected]",
  "language": "ruby",
  "description": "Fruit puzzler round 2",
  "contents": "def is_fruity?(thing);\n  end\n",
  "shared": true,
  "used": 0,
  "created_at": "2019-01-28T21:21:16Z",
  "updated_at": "2019-01-28T21:21:16Z"
}

The available paramters you have to configure are detailed below:

Field Description
id Primary key for the object. Use this to query or modify this resource later.
title Title for this question.
language One of a set list.
description Notes for yourself (or colleagues) on what this question is about, and what good and bad answers might look like.
contents This text is inserted into your interview session if you choose to use this question.

PUT /api/questions/:id (update)

Modifies an existing question. You can specify any of the valid parameters to create.

curl \
  -X PUT --data description="We've noticed candidates from the West coast have substantial experience with avocados, so this question is worth less points now." \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/questions/42

DELETE /api/questions/:id (destroy)

Deletes an existing question. There is no undo!

curl \
  -X DELETE \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/questions/42

The Quota Resource

GET /api/quota

This endpoint returns basic information about your organization’s monthly pad quota (or your quota, if you are not a part of an organization). For example, if you are a user in an organization with a monthly quota of 120 pads, the following:

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/quota

returns:

{
  "status": "OK",
  "trial_expires_at": "2018-01-30T16:16:00.000-08:00",
  "pads_used": 33,
  "quota_reset_at": "2018-01-25T14:51:37.084-08:00",
  "unlimited": false,
  "pads_remaining": 87,
  "monthly_pad_limit": 120
}

Fields returned:

Field Description
trial_expires_at The date your trial will expire, or has expired, in UTC ISO 8601 format (e.g., 2018-01-25T14:51:37.084-08:00).
pads_used The number of pads used during the current billing cycle.
quota_reset_at The date, in UTC ISO 8601, that your quota was last reset. Pad quotas are reset every billing cycle.
unlimited A boolean indicating whether your billing plan allows for unmetered usage.
pads_remaining The number of pads remaining for the current billing cycle. Not returned if unlimited is true.
monthly_pad_limit The total number of pads allocated for the billing cycle. Not returned if unlimited is true.

The Organization Resource

This endpoint allows you to access information about your organization, should you be a member of one: https://app.coderpad.io/api/organization.

GET /api/organization (show)

This endpoint returns basic information about your organization, including whether or not your organization makes use of a single-sign-on service for authentication.

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  https://app.coderpad.io/api/organization

returns

{
  "status": "OK",
  "organization_name": "ACME Computing",
  "user_count": 137,
  "users": [
    {
      "email": "[email protected]",
      "name": "Wile Coyote"
    }
    // ... followed by the rest of the users in your org.
  ],
  "default_language": "erlang", // default language for new users in your organization
  "single_sign_on_supported": true, // users will be directed to login via the single sign in portal
  "single_sign_in_url": acme.coderpad.io // the url for that portal.
}

GET /api/organization/stats

This endpoint returns statistics about how many pads the members of your organization have created. By default the endpoint will return information about the last 7 days, but you can configure the time range as well.

Parameter Values
start_time An ISO 8601 time string, specifying the start of the search window. If this parameter is specified, you must set end_time as well, and vice versa.
end_time An ISO 8601 time string specifying the end of the search window.
curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  "https://app.coderpad.io/api/organization/stats?\
start_time=2015-12-07T00:31:52Z&\
end_time=2015-12-15T00:31:52Z"

returns

{
  status: "OK",

  // The computed start/end times are always returned,
  // even with the default window
  start_time: 2023-03-23T01:56:35Z,
  end_time: 2023-03-31T01:56:35Z,

  pads_created: 137,
  users: [
    {
      email: "[email protected]",
      name: "Person Surname",
      pads_created: 7
    },
    {
      email: "[email protected]",
      name: "Confidant Methodical",
      pads_created: 0
    },
    // ... followed by the rest of the users in your org
  ]
}

GET /api/organization/pads (index)

This endpoint is similar to GET /api/pads (index), except that it returns all the pads in your organization. To access this endpoint, your user must be an organization owner, or your organization must allow all pads to be visible to its users. This last setting is default on, but you can email us to disable this feature.

The endpoint also performs sorting and pagination identically to GET /api/pads (index).

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  "https://app.coderpad.io/api/organization/pads?sort=updated_at,desc"

returns

{
  "status": "OK",
  "pads": [
    {
      "id": "PP7J474P",
      "title": "JavaScript Test",
      "owner_email": "[email protected]",
      "language": "javascript",
      "participants": ["Kristin", "Guest 104"],
      "contents": "var _ = require('underscore');\n...",
      "private": false,
      "execution_enabled": true,
      "events": "https://app.coderpad.io/api/pads/PP7J474P/events",
      "notes": "Brenda did a fantastic job talking through the prompt ...",
      "created_at": "2018-02-13T02:06:30Z",
      "updated_at": "2018-02-13T06:21:26Z",
      "ended_at": null,
      "url": "https://coderpad.io/PP7J474P",
      "playback": "https://coderpad.io/PP7J474P/playback",
      "history": "https://coderpadproject.firebaseio.com/PP7J474P/history.json",
      "drawing": "https://storage.googleapis.com/..."
    }
    // ... followed by a list of the rest of the pads in the organization
  ],
  "next_page": "https://app.coderpad.io/api/organization/pads?sort=updated_at,desc&page=2",
  "total": 512
}

GET /api/organization/questions (index)

This endpoint is similar to GET /api/questions (index), except that it returns all the questions in your organization visible to you. You’ll see your own questions as well as colleagues’ questions where the shared boolean is set to true. If you are an organization owner, you can see every question in the organization.

The endpoint also performs sorting and pagination identically to GET /api/questions (index).

curl \
  -H 'Authorization: Token token="8af9a3412559d803707937250dc1569d"' \
  "https://app.coderpad.io/api/organization/questions?sort=updated_at,desc"

returns

{
  "status": "OK",
  "questions": [
    {
      "id": 12,
      "title": "Are avocados fruity?",
      "owner_email": "[email protected]",
      "language": "ruby",
      "description": "Fruit puzzler round 2?",
      "contents": "def is_fruity?(thing);\\n  end\\n",
      "shared": true,
      "used": 0,
      "created_at": "2019-01-28T22:08:09Z",
      "updated_at": "2019-01-28T22:08:09Z"
    }
    // ... followed by the rest of the questions in the organization visible to you
  ],
  "next_page": "https://app.coderpad.io/api/organization/questions?sort=updated_at,desc&page=2",
  "total": 256
}

Appendix

Languages

When a resource contains a language field, it’s value is one of a set list:

Feedback?

The CoderPad Interview API is by no means finalized. If you find any problems or have any suggestions, please do not hesitate to email us.