NAV Navigation
Shell HTTP JavaScript Ruby Python PHP Java Go

Studio API v1.0.0

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

Mariana Tek's Studio API provides a set of purpose-built endpoints to make creating tools for managing studio configurations a breeze. The focused scope and utility of the Studio API endpoints encourages the use of our other APIs for goals like managing the finer details of existing objects or diving deep into their data for analytics.

Email: Support

Authentication

Layouts

Retrieve and manage First-Come-First-Serve and Pick-A-Spot Layouts.

Create Layout

Code samples

# You can also use wget
curl -X POST /api/studio/v1/layouts \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

POST /api/studio/v1/layouts HTTP/1.1

Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "Cool PAS Layout",
  "is_active": true,
  "classroom": {
    "id": "123"
  },
  "capacity": 3,
  "is_pick_a_spot": true,
  "spots": [
    {
      "name": "F1",
      "x_position": "3.5",
      "y_position": "2.1",
      "spot_type": {
        "id": "3"
      },
      "is_default_held": true
    },
    {
      "name": "F2",
      "x_position": "5.25",
      "y_position": "2.5",
      "spot_type": {
        "id": "3"
      },
      "is_default_held": false
    },
    {
      "name": "B1",
      "x_position": "1.5",
      "y_position": "1",
      "spot_type": {
        "id": "2"
      },
      "is_default_held": false
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('/api/studio/v1/layouts',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.post '/api/studio/v1/layouts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.post('/api/studio/v1/layouts', headers = headers)

print(r.json())

 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/api/studio/v1/layouts', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("/api/studio/v1/layouts");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/api/studio/v1/layouts", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

POST /api/studio/v1/layouts

Creates a new layout

Body parameter

{
  "name": "Cool PAS Layout",
  "is_active": true,
  "classroom": {
    "id": "123"
  },
  "capacity": 3,
  "is_pick_a_spot": true,
  "spots": [
    {
      "name": "F1",
      "x_position": "3.5",
      "y_position": "2.1",
      "spot_type": {
        "id": "3"
      },
      "is_default_held": true
    },
    {
      "name": "F2",
      "x_position": "5.25",
      "y_position": "2.5",
      "spot_type": {
        "id": "3"
      },
      "is_default_held": false
    },
    {
      "name": "B1",
      "x_position": "1.5",
      "y_position": "1",
      "spot_type": {
        "id": "2"
      },
      "is_default_held": false
    }
  ]
}

Parameters

Name In Type Required Description
body body any true Layout to create

Example responses

201 Response

{
  "id": "101",
  "name": "Cool PAS Layout",
  "is_active": true,
  "classroom": {
    "id": "123",
    "name": "Neat Classroom"
  },
  "capacity": 3,
  "is_pick_a_spot": true,
  "spots": [
    {
      "id": "11",
      "name": "F1",
      "x_position": "3.5",
      "y_position": "2.1",
      "spot_type": {
        "id": "3",
        "name": "Floor",
        "is_secondary": false
      },
      "is_default_held": true
    },
    {
      "id": "12",
      "name": "F2",
      "x_position": "5.25",
      "y_position": "2.5",
      "spot_type": {
        "id": "3",
        "name": "Floor",
        "is_secondary": false
      },
      "is_default_held": false
    },
    {
      "id": "13",
      "name": "B1",
      "x_position": "1.5",
      "y_position": "1",
      "spot_type": {
        "id": "2",
        "name": "Bike",
        "is_secondary": true
      },
      "is_default_held": false
    }
  ]
}

Responses

Status Meaning Description Schema
201 Created Layout created successfully. Layout
401 Unauthorized Authorization information is missing or invalid. None
403 Forbidden The authenticated user does not have permission to perform this request. None
422 Unprocessable Entity Request is invalid. None

List Layouts

Code samples

# You can also use wget
curl -X GET /api/studio/v1/layouts \
  -H 'Accept: application/json'

GET /api/studio/v1/layouts HTTP/1.1

Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('/api/studio/v1/layouts',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.get '/api/studio/v1/layouts',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('/api/studio/v1/layouts', headers = headers)

print(r.json())

 'application/json',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/api/studio/v1/layouts', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("/api/studio/v1/layouts");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/api/studio/v1/layouts", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /api/studio/v1/layouts

Returns a list of layouts along with their spot data

Parameters

Name In Type Required Description
id query string false filter by layout ID
classroom query string false filter by a classroom ID
is_pick_a_spot query boolean false filter by layout format
page query integer false specific page number to return records from
page_size query integer false maximum number of records to return per page

Example responses

200 Response

{
  "results": [
    {
      "id": "101",
      "name": "Cool PAS Layout",
      "is_active": true,
      "classroom": {
        "id": "123",
        "name": "Neat Classroom"
      },
      "capacity": 3,
      "is_pick_a_spot": true,
      "spots": [
        {
          "id": "11",
          "name": "F1",
          "x_position": "3.5",
          "y_position": "2.1",
          "spot_type": {
            "id": "3",
            "name": "Floor",
            "is_secondary": false
          },
          "is_default_held": true
        },
        {
          "id": "12",
          "name": "F2",
          "x_position": "5.25",
          "y_position": "2.5",
          "spot_type": {
            "id": "3",
            "name": "Floor",
            "is_secondary": false
          },
          "is_default_held": false
        },
        {
          "id": "13",
          "name": "B1",
          "x_position": "1.5",
          "y_position": "1",
          "spot_type": {
            "id": "2",
            "name": "Bike",
            "is_secondary": true
          },
          "is_default_held": false
        }
      ]
    }
  ],
  "meta": {
    "pagination": {
      "count": 1,
      "pages": 1,
      "page": 1
    }
  }
}

Responses

Status Meaning Description Schema
200 OK Search results matching criteria. LayoutList
404 Not Found The specified resource cannot be found. None
422 Unprocessable Entity Request is invalid. None

Retrieve Layout

Code samples

# You can also use wget
curl -X GET /api/studio/v1/layouts/{layout_id} \
  -H 'Accept: application/json'

GET /api/studio/v1/layouts/{layout_id} HTTP/1.1

Accept: application/json


const headers = {
  'Accept':'application/json'
};

fetch('/api/studio/v1/layouts/{layout_id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Accept' => 'application/json'
}

result = RestClient.get '/api/studio/v1/layouts/{layout_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Accept': 'application/json'
}

r = requests.get('/api/studio/v1/layouts/{layout_id}', headers = headers)

print(r.json())

 'application/json',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/api/studio/v1/layouts/{layout_id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("/api/studio/v1/layouts/{layout_id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/api/studio/v1/layouts/{layout_id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

GET /api/studio/v1/layouts/{layout_id}

View details of one particular layout

Example responses

200 Response

{
  "id": "202",
  "name": "Fun FCFS Layout",
  "is_active": true,
  "classroom": {
    "id": "123",
    "name": "Neat Classroom"
  },
  "capacity": 5,
  "is_pick_a_spot": false,
  "spots": null
}

Responses

Status Meaning Description Schema
200 OK Success. Layout
404 Not Found The specified resource cannot be found. None

Update Layout

Code samples

# You can also use wget
curl -X PATCH /api/studio/v1/layouts/{layout_id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access-token}'

PATCH /api/studio/v1/layouts/{layout_id} HTTP/1.1

Content-Type: application/json
Accept: application/json

const inputBody = '{
  "name": "Cool PAS Layout",
  "is_active": false,
  "spots": [
    {
      "id": "11",
      "name": "F1",
      "x_position": "3.5",
      "y_position": "2.1"
    },
    {
      "id": "12",
      "name": "F2",
      "x_position": "5.25",
      "y_position": "2.5"
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'Authorization':'Bearer {access-token}'
};

fetch('/api/studio/v1/layouts/{layout_id}',
{
  method: 'PATCH',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

require 'rest-client'
require 'json'

headers = {
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer {access-token}'
}

result = RestClient.patch '/api/studio/v1/layouts/{layout_id}',
  params: {
  }, headers: headers

p JSON.parse(result)

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer {access-token}'
}

r = requests.patch('/api/studio/v1/layouts/{layout_id}', headers = headers)

print(r.json())

 'application/json',
    'Accept' => 'application/json',
    'Authorization' => 'Bearer {access-token}',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PATCH','/api/studio/v1/layouts/{layout_id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

URL obj = new URL("/api/studio/v1/layouts/{layout_id}");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("PATCH");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(
    new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    response.append(inputLine);
}
in.close();
System.out.println(response.toString());

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "Authorization": []string{"Bearer {access-token}"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PATCH", "/api/studio/v1/layouts/{layout_id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

PATCH /api/studio/v1/layouts/{layout_id}

Update an existing layout

Body parameter

{
  "name": "Cool PAS Layout",
  "is_active": false,
  "spots": [
    {
      "id": "11",
      "name": "F1",
      "x_position": "3.5",
      "y_position": "2.1"
    },
    {
      "id": "12",
      "name": "F2",
      "x_position": "5.25",
      "y_position": "2.5"
    }
  ]
}

Parameters

Name In Type Required Description
body body object true Layout details to update. On layouts, only the "name" and "is_active" properties can be modified. For Pick-A-Spot layouts, you can additionally update some spot-specific properties ("name", "x_position", and "y_position" only).

Example responses

200 Response

{
  "id": "101",
  "name": "Cool PAS Layout",
  "is_active": false,
  "classroom": {
    "id": "123",
    "name": "Neat Classroom"
  },
  "capacity": 3,
  "is_pick_a_spot": true,
  "spots": [
    {
      "id": "11",
      "name": "F1",
      "x_position": "3.5",
      "y_position": "2.1",
      "spot_type": {
        "id": "3",
        "name": "Floor",
        "is_secondary": false
      },
      "is_default_held": true
    },
    {
      "id": "12",
      "name": "F2",
      "x_position": "5.25",
      "y_position": "2.5",
      "spot_type": {
        "id": "3",
        "name": "Floor",
        "is_secondary": false
      },
      "is_default_held": false
    },
    {
      "id": "13",
      "name": "B1",
      "x_position": "1.5",
      "y_position": "1",
      "spot_type": {
        "id": "2",
        "name": "Bike",
        "is_secondary": true
      },
      "is_default_held": false
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK Updated successfully. Layout
401 Unauthorized Authorization information is missing or invalid. None
403 Forbidden The authenticated user does not have permission to perform this request. None
404 Not Found The specified resource cannot be found. None
422 Unprocessable Entity Request is invalid. None

Schemas

LayoutList

{
  "results": [
    {
      "id": "101",
      "name": "Cool PAS Layout",
      "is_active": true,
      "classroom": {
        "id": "123",
        "name": "Neat Classroom"
      },
      "capacity": 3,
      "is_pick_a_spot": true,
      "spots": [
        {
          "id": "11",
          "name": "F1",
          "x_position": "3.5",
          "y_position": "2.1",
          "spot_type": {
            "id": "3",
            "name": "Floor",
            "is_secondary": false
          },
          "is_default_held": true
        },
        {
          "id": "12",
          "name": "F2",
          "x_position": "5.25",
          "y_position": "2.5",
          "spot_type": {
            "id": "3",
            "name": "Floor",
            "is_secondary": false
          },
          "is_default_held": false
        },
        {
          "id": "13",
          "name": "B1",
          "x_position": "1.5",
          "y_position": "1",
          "spot_type": {
            "id": "2",
            "name": "Bike",
            "is_secondary": true
          },
          "is_default_held": false
        }
      ]
    }
  ],
  "meta": {
    "pagination": {
      "count": 1,
      "pages": 1,
      "page": 1
    }
  }
}

Properties

Name Type Required Restrictions Description
results [Layout] false read-only A list of Layouts
meta Meta false none Pagination metadata.

Layout

{
  "id": "101",
  "name": "Cool PAS Layout",
  "is_active": true,
  "classroom": {
    "id": "123",
    "name": "Neat Classroom"
  },
  "capacity": 3,
  "is_pick_a_spot": true,
  "spots": [
    {
      "id": "11",
      "name": "F1",
      "x_position": "3.5",
      "y_position": "2.1",
      "spot_type": {
        "id": "3",
        "name": "Floor",
        "is_secondary": false
      },
      "is_default_held": true
    },
    {
      "id": "12",
      "name": "F2",
      "x_position": "5.25",
      "y_position": "2.5",
      "spot_type": {
        "id": "3",
        "name": "Floor",
        "is_secondary": false
      },
      "is_default_held": false
    },
    {
      "id": "13",
      "name": "B1",
      "x_position": "1.5",
      "y_position": "1",
      "spot_type": {
        "id": "2",
        "name": "Bike",
        "is_secondary": true
      },
      "is_default_held": false
    }
  ]
}

Properties

Name Type Required Restrictions Description
id string true read-only none
name string true none none
is_active boolean true none Only Active Layouts can be used in Classes.
classroom Classroom true none none
capacity integer true none If is_pick_a_spot=true, capacity must match length of spots array with a Maximum of 100. If is_pick_a_spot=false, capacity will set number of spots in First-Come-First-Serve layout with a Maximum of 1000.
is_pick_a_spot boolean true none Determines whether the Layout format consists of discrete spots on a map (Pick-A-Spot) or a simple roster (First-Come-First-Serve).
spots [Spot]¦null true none If is_pick_a_spot=false, then spots=null.

Classroom

{
  "id": "123",
  "name": "Neat Classroom"
}

Properties

Name Type Required Restrictions Description
id string true none none
name string false read-only none

Spot

{
  "id": "11",
  "name": "F1",
  "x_position": "3.5",
  "y_position": "2.1",
  "spot_type": {
    "id": "3",
    "name": "Floor",
    "is_secondary": false
  },
  "is_default_held": true
}

Properties

Name Type Required Restrictions Description
id string true read-only none
name string true none none
x_position string(decimal) true none Stringified decimal representation of X position on map. Up to 5 digits total, and 2 decimal places. Spots should be at least 1.0 apart to avoid overlapping
y_position string(decimal) true none Stringified decimal representation of Y position on map. Up to 5 digits total, and 2 decimal places. Spots should be at least 1.0 apart to avoid overlapping
spot_type SpotType true none none
is_default_held boolean false none none

SpotType

{
  "id": "3",
  "name": "Floor",
  "is_secondary": false
}

Properties

Name Type Required Restrictions Description
id string true none none
name string false read-only none
is_secondary boolean false read-only If is_default_held=true, the spot won't be available for booking unless the hold is released for a particular class.

Meta

{
  "pagination": {
    "count": 1,
    "pages": 1,
    "page": 1
  }
}

Pagination metadata.

Properties

Name Type Required Restrictions Description
pagination object false none Pagination information.
» count integer false read-only The total number of items.
» pages integer false read-only The total number of pages.
» page integer false none The current page.