Decks ๐Ÿ”—

A Deck allows an ordered collection of analyses to be stored for future use or for export. Each deck belongs to a dataset and its analyses are drawn from that single dataset. A deck is personal to the user that created it unless the deck has been set โ€œpublicโ€. Each deck contains a sequence of slides, and each slide contains an analysis. Additional analyses can be associated with a slide, but only the first one appears in the UI or on export.

Catalog ๐Ÿ”—

/datasets/{id}/decks/

GET ๐Ÿ”—

A GET request on the catalog endpoint will return all decks in this dataset that are accessible to the current user. This includes decks created by the user, as well as all public decks in the dataset.

{
    "element": "shoji:catalog",
    "self": "https://app.crunch.io/api/datasets/223fd4/decks/",
    "index": {
        "https://app.crunch.io/api/datasets/cc9161/decks/4fa25/": {
          "name": "my new deck",
          "creation_time": "1986-11-26T12:05:00",
          "id": "4fa25",
          "is_public": false,
          "owner_id": "https://app.crunch.io/api/users/abcd3/",
          "owner_name": "Real Person",
          "team": null
        },
        "https://app.crunch.io/api/datasets/cc9161/decks/2b53e/": {
          "name": "Default deck",
          "creation_time": "1987-10-15T11:45:00",
          "id": "2b53e",
          "is_public": true,
          "owner_id": "https://app.crunch.io/api/users/4cba5/",
          "owner_name": "Other Person",
          "team": "https://app.crunch.io/api/teams/58acf7/"
        }
    },
    "order": "https://app.crunch.io/api/datasets/223fd4/decks/order/"
}

The deck catalog tuples contain the following keys:

Name Type Description
name string Human-friendly string identifier
creation_time timestamp Time when this deck was created
id string Global unique identifier for this deck
is_public boolean Indicates whether this is a public deck or not
owner_id url Points to the owner of this deck
owner_name string Name of the owner of the deck (referred by owner_id)
team url If the deck is shared through a team, it will point to it. null by default

To determine if a deck belongs to the current user, check the owner_id attribute.

POST ๐Ÿ”—

POST a shoji:entity to create a new deck for this dataset. The only required body attribute is โ€œnameโ€; other attributes are optional.

{
    "element": "shoji:entity",
    "self": "https://app.crunch.io/api/datasets/223fd4/decks/",
    "body": {
        "name": "my new deck",
        "description": "This deck will contain analyses for a variable",
        "is_public": false,
        "team": "https://app.crunch.io/api/teams/58acf7/"
    }
}
HTTP/1.1 201 Created
Location: https://app.crunch.io/api/datasets/223fd4/decks/2b3c5e/

The shoji:entity POSTed accepts the following keys

Name Type required
name string Yes
description string No
is_public boolean No
team url No

PATCH ๐Ÿ”—

It is possible to bulk-edit multiple decks at once by PATCHing a shoji:catalog to the deck catalog endpoint.

{
    "element": "shoji:catalog",
    "index": {
        "https://app.crunch.io/api/datasets/cc9161/decks/4fa25/": {
          "name": "Renamed deck",
          "is_public": true
        }
    },
    "order": "https://app.crunch.io/api/datasets/223fd4/decks/order/"
}

The following attributes are editable via PATCHing this resource:

  • name
  • description
  • is_public

For decks that the current user owns, โ€œnameโ€, โ€œdescriptionโ€ and โ€œis_publicโ€ are editable. Only the deck owner can edit the mentioned attributes on a deck even if the deck is public. Other deck attributes are not editable and will respond with 400 status if the request tries to change them.

On success, the server will respond with status code 204 (No Content).

Public decks cannot contain analyses that refer to secure variables. Attempting to create one results in a 400 response. Hidden variables, however, are permitted.

Entity ๐Ÿ”—

/datasets/{id}/decks/{id}/

GET ๐Ÿ”—

GET a deck entity resource to return a shoji:entity with all of its attributes:

{
    "element": "shoji:entity",
    "self": "https://app.crunch.io/api/datasets/223fd4/decks/223fd4/",
    "body": {
        "name": "Presentation deck",
        "id": "223fd4",
        "creation_time": "1987-10-15T11:45:00",
        "description": "Explanation about the deck",
        "is_public": false,
        "owner_id": "https://app.crunch.io/api/users/abcd3/",
        "owner_name": "Real Person",
        "team": "https://app.crunch.io/api/teams/58acf7/"
    }
}
Name Type Description
name string Human-friendly string identifier
id string Global unique identifier for this deck
creation_time timestamp Time when this deck was created
description string Longer annotations for this deck
is_public boolean Indicates whether this is a public deck or not
owner_id url Points to the owner of this deck
owner_name string Name of the owner of the deck (referred by owner_id)
team url If the deck is shared through a team, it will point to it. null by default

PATCH ๐Ÿ”—

To edit a deck, PATCH it with a shoji:entity. The server will return a 204 response on success or 400 if the request is invalid.

{
    "element": "shoji:entity",
    "self": "https://app.crunch.io/api/datasets/223fd4/decks/223fd4/",
    "body": {
        "name": "Presentation deck",
        "id": "223fd4",
        "creation_time": "1987-10-15T11:45:00",
        "description": "Explanation about the deck",
        "team": "https://app.crunch.io/api/teams/58acf7/"
    },
    "catalogs": {
        "slides": "https://app.crunch.io/api/datasets/223fd4/decks/223fd4/slides/"
    },
    "views": {
        "export": "https://app.crunch.io/api/datasets/223fd4/decks/223fd4/export/"
    }
}
HTTP/1.1 204 No Content

For deck entities that the current user owns, โ€œnameโ€, โ€œdescriptionโ€, โ€œteamsโ€ and โ€œis_publicโ€ are editable. Other deck attributes are not editable.

Attempting to PATCH is_public: true to a deck containing an analysis that references a secure variable will receive a 400 response.

DELETE ๐Ÿ”—

To delete a deck, DELETE the deckโ€™s entity URL. On success, the server returns a 204 response.

Deck Exports ๐Ÿ”—

xlsx ๐Ÿ”—

A successful POST request to /datasets/{dataset_id}/decks/{deck_id}/export/ will generate a download location to which the exporter will write this file when done computing (large datasets may take some time). The server will return 202 (Accepted) indicating the export job started, along with a Location header indicating where the exported file will be available. The response body will contain a progress URL on which export completion status may be queried. Clients should note the download URL, monitor progress, and when complete, GET the download location. See Progress for details. If no header is provided on the POST, this endpoint will produce an xlsx file.

Requesting the same job, if still in progress, will return the same 202 response indicating the original progress to check. If the export is finished, the server will respond 302 (Found), redirecting to the download location.

If dataset attributes have changed since a pending POST, a new POST will respond 202 (Accepted) and generate a new tab book, regardless of the status of the pending export.

Note: If desired, you can provide an Accept: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet header to explicitly specify Excel (xlsx) download format. If no Accept header is provided, the default download will be xlsx.

json ๐Ÿ”—

Providing an Accept: application/json header for this endpoint produces a JSON export of the deck payload. This is the same JSON used to form an XLSX or PPTX deck export and contains an analysis for each slide in the deck.

{
  "slides": [
    {
      "cube": {
        "query": {
          "measures": {
            "count": {
              "function": "cube_count",
              "args": []
            }
          },
          "dimensions": [
            {
              "function": "bin",
              "args": [
                {
                  "variable": "000001"
                }
              ]
            },
            {
              "variable": "000000"
            }
          ],
          "weight": null
        },
        "query_environment": {
          "filter": []
        },
        "result": {
          "dimensions": [
            {
              "references": {
                "alias": "Age",
                "description": null,
                "name": "Age"
              },
              "derived": true,
              "type": {
                "subtype": {
                  "missing_rules": {},
                  "class": "numeric",
                  "missing_reasons": {
                    "No Data": -1
                  }
                },
                "elements": [
                  {
                    "id": 1,
                    "value": [10.0, 20.0],
                    "missing": false
                  },
                  {
                    "id": 2,
                    "value": [20.0, 30.0],
                    "missing": false
                  },
                  {
                    "id": 3,
                    "value": [30.0, 40.0],
                    "missing": false
                  },
                  {
                    "id": 4,
                    "value": [40.0, 50.0],
                    "missing": false
                  }
                ],
                "class": "enum"
              }
            },
            {
              "references": {
                "alias": "Gender",
                "description": null,
                "name": "Gender"
              },
              "derived": false,
              "type": {
                "ordinal": false,
                "class": "categorical",
                "categories": [
                  {
                    "numeric_value": null,
                    "id": 2,
                    "name": "F",
                    "missing": false
                  },
                  {
                    "numeric_value": null,
                    "id": 1,
                    "name": "M",
                    "missing": false
                  }
                ]
              }
            }
          ],
          "missing": 0,
          "measures": {
            "count": {
              "data": [1, 3, 0, 0, 1, 0, 1, 1],
              "n_missing": 0,
              "metadata": {
                "references": {},
                "derived": true,
                "type": {
                  "integer": true,
                  "missing_rules": {},
                  "class": "numeric",
                  "missing_reasons": {
                    "No Data": -1
                  }
                }
              }
            }
          },
          "n": 7,
          "counts": [1, 3, 0, 0, 1, 0, 1, 1],
          "element": "crunch:cube"
        }
      },
      "meta": {
        "table_title": "",
        "name": "Slide #1 ",
        "weight": null,
        "title": "Slide #1",
        "filters": [],
        "subtitle": "",
        "display_settings": {
          "decimalPlaces": {
            "value": 2
          }
        }
      }
    }
  ],
  "dataset": {
    "notes": "",
    "name": "New dataset"
  }
}

Order ๐Ÿ”—

/datasets/{id}/decks/order/

The deck order resource allows the user to arrange how API clients, such as the web application, will present the deck catalog. The deck order contains all decks that are visible to the current user, both personal and public. Unlike many other shoji:order resources, this order does not allow grouping or nesting: it will always be a flat list of deck URLs.

GET ๐Ÿ”—

Returns a Shoji Order response.

{
  "element": "shoji:order",
  "self": "https://app.crunch.io/api/datasets/223fd4/decks/order/",
  "graph": [
    "https://app.crunch.io/api/datasets/223fd4/decks/1/",
    "https://app.crunch.io/api/datasets/223fd4/decks/2/",
    "https://app.crunch.io/api/datasets/223fd4/decks/3/"
  ]
}

PATCH ๐Ÿ”—

PATCH the order resource to change the order of the decks. A 204 (No Content) response indicates success.

If the PATCH payload contains only a subset of available decks, those decks not referenced will be appended at the bottom of the top level graph in arbitrary order.

{
  "element": "shoji:order",
  "self": "https://app.crunch.io/api/datasets/223fd4/decks/order/",
  "graph": [
    "https://app.crunch.io/api/datasets/223fd4/decks/1/",
    "https://app.crunch.io/api/datasets/223fd4/decks/3/"
  ]
}

Including invalid URLs, such as URLs of decks that are not present in the catalog, will return a 400 response from the server.

The deck order should always be a flat list of URLs. Nesting or grouping is not supported by the web application. Server will return a 400 response if the order supplied in the PATCH request has nesting.

Slides ๐Ÿ”—

Each deck contains a catalog of slides in which analyses are saved.

Catalog ๐Ÿ”—

/datasets/{id}/decks/{deck_id}/slides/

GET ๐Ÿ”—

Returns a shoji:catalog with the slides for this deck.

{
    "element": "shoji:catalog",
    "self": "https://app.crunch.io/api/datasets/123/decks/123/slides/",
    "orders": {
        "flat": "https://app.crunch.io/api/datasets/123/decks/123/slides/flat/"
    },
    "specification": "https://app.crunch.io/api/specifications/slides/",
    "description": "A catalog of the Slides in this Deck",
    "index": {
        "https://app.crunch.io/api/datasets/123/decks/123/slides/123/": {
            "analysis_url": "https://app.crunch.io/api/datasets/123/decks/123/slides/123/analyses/123/",
            "subtitle": "z",
            "display_settings": {
                "vizType": {
                    "value": "table"
                }
            },
            "type": "analysis",
            "title": "slide 1"
        },
        "https://app.crunch.io/api/datasets/123/decks/123/slides/456/": {
            "analysis_url": "https://app.crunch.io/api/datasets/123/decks/123/slides/456/",
            "subtitle": "",
            "display_settings": {
                "vizType": {
                    "value": "table"
                }
            },
            "type": "analysis",
            "title": "slide 2"
        },
        "https://app.crunch.io/api/datasets/123/decks/123/slides/789/": {
            "title": "slide 3",
            "subtitle": "",
            "type": "markdown",
            "markdown": "# Some markdown\ntext"
        }
    }
}

Each tuple on the slides catalog contains the following keys:

Name Type Description
analysis_url url Points to the first (and typically only) analysis contained on this slide
title string Optional title for the slide
subtitle string Optional subtitle for the slide
type string Defaults to โ€œanalysisโ€, only other value is โ€œmarkdownโ€
display_settings object Stores settings used to load the analysis

POST ๐Ÿ”—

To create a new slide, POST a slide body to the slides catalog. If no type is indicated, the new slide will default to an analysis, and it must include at least one analysis. In the case of type markdown, a markdown text field should be included.

For analysis type, the body must contain an analyses array item containing one or more analysis bodies as described in the Analysis section. The body should be wrapped as a shoji:entity.

Note, that on markdown type, the server will reject analyses being sent, and in the case of analysis type, the server will reject markdown field.

On success, the server returns a 201 (Created) response with a Location header containing the URL of the newly created slide entity.

Because public decks cannot contain analyses that refer to secure variables, attempting to create a slide on a public deck that references one results in a 400 response. Hidden variables, however, are permitted.

{
  "title": "New slide",
  "subtitle": "Variable A and B",
  "analyses": [
    {
      "query": {},
      "query_environment": {},
      "display_settings": {}
    },
    {
      "query": {},
      "query_environment": {},
      "display_settings": {}
    }
  ]
}

On each analysis, only a query field is required to create a new slide; other attributes are optional.

To add a markdown slide:

{
  "title": "New slide",
  "subtitle": "Variable A and B",
  "type": "markdown",
  "markdown": "# Title\n##Subtitle\n\nparagraph",
}

Slide attributes:

Name Type Description
title string Optional title for the slide
subtitle string Optional subtitle for the slide
type string Defaults to โ€œanalysisโ€

Analysis attributes:

Name Type Description
query object Contains a valid analysis query, required
subtitle string Optional subtitle for the slide
display_settings object Contains a set of attributes to be interpreted by the client to render and export the analysis
query_environment object

Contains the weight and filter applied during the analysis, they will be applied upon future evaluation/render/export.

The weight value must be a variable URL, null or the weight key may be omitted. A variable URL must correspond to a variable in the weight_variables collection for the dataset. A value of null indicates unweighted. When the weight key is omitted, the current-weight of the user making the evaluation/render/export request (not necessarily the user who created the slide) is used and can vary between users.

transform object Contains a transformations specifier object.

Old format ๐Ÿ”—

It is possible to create a slide with analysis in a single call by POSTing an analysis body directly to the slides catalog. This will create a slide containing the new analysis:

{
  "title": "New slide",
  "subtitle": "Variable A and B",
  "query": {},
  "query_environment": {},
  "display_settings": {},
  "transform": {}
}

PATCH ๐Ÿ”—

It is possible to bulk-edit several slides at once by PATCHing a shoji:catalog to this endpoint.

The only editable attributes with this method are:

  • title
  • subtitle

Other attributes should be considered read-only.

Submitting invalid attributes or references to other slides results in a 400 error response.

To edit the first or any of the slideโ€™s analyses query attributes it is necessary to PATCH the individual analysis entity.

Entity ๐Ÿ”—

/datasets/223fd4/decks/slides/a126ce/

Each slide in the Slide Catalog contains a reference to its first analysis.

GET ๐Ÿ”—

{
    "element": "shoji:entity",
    "self": "/api/datasets/123/decks/123/slides/123/",
    "catalogs": {
        "analyses": "/api/datasets/123/decks/123/slides/123/analyses/"
    },
    "description": "Returns the detail information for a given slide",
    "body": {
        "deck_id": "123",
        "subtitle": "z",
        "title": "slide 1",
        "analysis_url": "/api/datasets/123/decks/123/slides/123/analyses/123/",
        "display_settings": {
            "vizType": {
                "value": "table"
            }
        },
        "transform": {},
        "id": "123"
    }
}

DELETE ๐Ÿ”—

Perform a DELETE request on the Slide entity resource to delete the slide and its analyses.

PATCH ๐Ÿ”—

It is possible to edit a slide entity by PATCHing with a shoji:entity.

The editable attributes are:

  • title
  • subtitle

The other attributes are considered read-only.

Order ๐Ÿ”—

/datasets/223fd4/decks/slides/flat/

The owner of the deck can specify the order of its slides. As with deck order, the slide order must be a flat list of slide URLs.

GET ๐Ÿ”—

Returns the list of all the slides in the deck.

{
    "element": "shoji:order",
    "self": "/api/datasets/123/decks/123/slides/flat/",
    "description": "Order of the slides on this deck",
    "graph": [
        "/api/datasets/123/decks/123/slides/123/",
        "/api/datasets/123/decks/123/slides/456/"
    ]
}

PATCH ๐Ÿ”—

To make changes to the order, a client should PATCH the full shoji:order resource to the endpoint with the new order on its graph attribute.

Any slide not mentioned on the payload will be added at the end of the graph in arbitrary order.

{
    "element": "shoji:order",
    "self": "/api/datasets/123/decks/123/slides/flat/",
    "description": "Order of the slides on this deck",
    "graph": [
        "/api/datasets/123/decks/123/slides/123/",
        "/api/datasets/123/decks/123/slides/456/"
    ]
}

This is a flat order: grouping or nesting is not allowed. PATCHing with a nested order will generate a 400 response.

Analysis ๐Ÿ”—

Each slide contains one or more analyses. An analysis โ€“ a table or graph with some specific combination of variables defining measures, rows, columns, and tabs; and settings such as percentage direction and decimal places โ€“ can be saved to a deck, which can then be exported, or the analysis can be reloaded in whole in the application or even exported as a standalone embeddable result. Note that while a slide can have multiple analyses, only the first analysis for each slide is used when exporting to Excel or PowerPoint.

Catalog ๐Ÿ”—

/api/datasets/123/decks/123/slides/123/analyses/

POST ๐Ÿ”—

To create multiple analyses on a slide, clients should POST analyses to the slideโ€™s analyses catalog.

{
    "query": {
        "dimensions" : [],
        "measures": {}
    },
    "query_environment": {
        "filter": [
            {"filter": "<url>"},
            {"function": "expression", "args": [], "name": "(Optional)"}
        ],
        "weight": "url"
    },
    "display_settings": {
        "decimalPlaces": {
            "value": 0
        },
        "percentageDirection": {
            "value": "colPct"
        },
        "vizType": {
            "value": "table"
        },
        "countsOrPercents": {
            "value": "percent"
        },
        "uiView": {
            "value": "expanded"
        }
    },
    "transform": {}
}

The weight item must be a variable-URL, null, or the key may be omitted. A variable-URL must correspond to a variable in the weight_variables collection for the dataset. A value of null indicates unweighted. When the weight key is omitted, the current-weight of the user making the evaluate/render/export request (not necessarily the user who created the analysis) is used and may vary between users.

The server will return a 201 (Created) response with the new slide created. In case of invalid analysis attributes, a 400 (Bad Request) response will be returned indicating the problem.

Because public decks cannot contain analyses that refer to secure variables, attempting to add analyses that reference one results in a 400 response. Hidden variables, however, are permitted.

PATCH ๐Ÿ”—

It is possible to delete many analyses at once from the catalog sending null as their tuple. It is not possible to delete all the analysis from a slide. For that it is necessary to delete the slide itself.

{
    "/api/datasets/123/decks/123/slides/123/analyses/1/": null,
    "/api/datasets/123/decks/123/slides/123/analyses/2/": {}
}

A 204 response will be returned on success.

Order ๐Ÿ”—

As analyses get added to a slide, they will be stored on a shoji:order resource.

Like other order resources, it will expose a graph attribute that contains the list of created analyses having new ones added at the end.

If an incomplete set of analyses is sent to the graph, the missing analyses will be added in arbitrary order.

This is a flat order and does not allow nesting.

Entity ๐Ÿ”—

An analysis is defined by a query, query environment, and display settings. To save an analysis, POST these to a deck as a new slide.

Display settings can be anything a client may need to reproduce the view of the data returned from the query. The settings the Crunch web client uses are shown here, but other clients are free to store other attributes as they see fit. Display settings should be objects with a value member.

{
    "query": {
        "dimensions" : [],
        "measures": {}
    },
    "query_environment": {
        "filter": [
            {"filter": "<url>"},
            {"function": "expression", "args": [], "name": "(Optional)"}
        ],
        "weight": "url"
    },
    "display_settings": {
        "decimalPlaces": {
            "value": 0
        },
        "percentageDirection": {
            "value": "colPct"
        },
        "vizType": {
            "value": "table"
        },
        "countsOrPercents": {
            "value": "percent"
        },
        "uiView": {
            "value": "expanded"
        }
    },
    "transform": {}
}
Name Description
query Includes the query body for this analysis
query_environment

An object with a weight and filters to be used for rendering/evaluating this analysis

The weight item must be a variable-URL, null, or the key may be omitted. A variable-URL must correspond to a variable in the weight_variables collection for the dataset. A value of null indicates unweighted. When the weight key is omitted, the current-weight of the user making the evaluate/render/export request is used and may vary between users.

display_settings An object containing client-specific instructions on how to recreate the analysis
transform An object containing client-specific instructions on how to manipulate the rendering of the analysis

PATCH ๐Ÿ”—

To edit an analysis, PATCH its URL with a shoji:entity.

The editable attributes are:

  • query
  • query_environment
  • display_settings
  • transform

Providing invalid values for those attributes or extra attributes will be rejected with a 400 response from the server.

Editing an analysis query on a public deck cannot add reference to a secure variable; such a request results in a 400 response. Hidden variables, however, are permitted.

DELETE ๐Ÿ”—

It is possible to delete analyses from a slide as long as there is always one analysis left.

Attempting to delete the last analysis of a slide will cause a 409 response from the server indicating the problem.