Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Documentation for integrating with Cappasity 3D Platform

(c) Copyright 2017-2021, Cappasity Inc. All rights reserved.

Registering an account and getting an API key

  1. Register using link
  2. Complete email verification. If you are using custom domain - email might be a bit slow to come due to "graylisting". However it should arrive soon. If not - check back with us, we'll help.
  3. Go to account page - - and create a security token, you will need this for interacting with API. Please securely store it somewhere - you will not be able to see created token again for security reasons

Uploading 3D View or 3D models

  1. Use Easy 3D Scan software to prepare your 3D Views and upload them to Cappasity platform.
  2. For ease of integration assign SKU to the models you are uploading - this is a user generated alias, which can be used to programmatically access existing models and generate embeddable iframe code on the go.
  3. If you do not assign SKUs right away - it can be done manually through our website interface via "edit model" feature.

API methods and considerations

There are 2 ways to integrate with us - for testing & debugging you might use embed button, which will allow you to select different settings, size of the iframe and receive iframe code right away. However, when you are working with large amounts of models it might be most convenient to use API to generate iframe code. It won't change unless you change settings - so it's advised to cache it to reduce latency and amount of requests your server is performing. Consider Cappasity API rate limits.

Get embed code based on SKU

  1. We support gzip, if you want it to work - pass 'Accept-Encoding: gzip', with curl automatically encoding/decoding is performed with --compressed options
  2. We strive to comply with scheme, and because of that we respond with application/vnd.api+json content-type, it's essentially the same as application/json, but notifies you that we are following this specification
  3. We expect you to send the content in the format of jsonapi, so please, specify Content-Type: application/vnd.api+json header
  4. This request requires authentication - specify Authorization: Bearer <your-token> Header
  5. To ensure consistent versions of the API, you can pass an extra header of Accept-Version: ~1 which would tell that you want to receive response of the version 1 API. In the future if we change something - nothing will break in your integration

This is a sample CURL request for this method. For a more detailed example in javascript, check sku-embed.js sample

curl -X POST --compressed \
  -H "Content-Type: application/vnd.api+json" \
  -H "Authorization: Bearer hash.token.signature" \
  "" \
  -d '{
    "data": {
      "id": "sku2137189",
      "type": "embed",
      "attributes": {
        "width": 100,
        "height": 600,
        "autorun": true,
        "closebutton": true,
        "hidecontrols": false,
        "logo": true,
        "hidefullscreen": false

HTTP response will have statusCode 200 and contain the following JSON data structure in the body:

  "meta": {
    "id": "request-id"
  "data": "iframe code"

Get embed code based on Cappasity URL

If you have a cappasity 3d URL, such as, you may retrieve customized player URL. Quick example is provided below. Please look at sample code for a complete set of options

curl -X POST --compressed \
  -H "Content-Type: application/vnd.api+json" \
  -H "Authorization: Bearer hash.token.signature" \
  "" \
  -d '{
    "data": {
      "type": "embed",
      "attributes": {
        "width": 100,
        "height": 600

HTTP response will have statusCode 200 and contain the following JSON data structure in the body:

    "meta": {
      "id": "<request id>"
    "data": {
      "id": "<user id>/<model id>",
      "type": "embed",
      "attributes": {
        "html": "<iframe ...></iframe>"

Player customization options

Accepted attributes are:

Parameter Type Default Description
width integer, >= 100 100 iFrame width, px or %. Treated as 100% when set at 100, otherwise in px
height integer, >= 100 600 iFrame height, px or %. Treated as 100% when set at 100, otherwise in px
autorun boolean false Whether to start the player (widget) automatically or display the preview and play button
closebutton boolean true Show close button
logo boolean true Show Cappasity logo
analytics boolean true Enable analytics
autorotate boolean false Start automatic rotation
autorotatetime float 10 Rotation time of the full turn, seconds
autorotatedelay float 2 Delay if rotation was interrupted, seconds
autorotatedir integer 1 Autorotate direction (clockwise is 1, counter-clockwise is -1)
hidefullscreen boolean true Hide fullscreen view button
hideautorotateopt boolean true Hide autorotate button
hidesettingsbtn boolean false Hide settings button
enableimagezoom boolean true Enable zoom
zoomquality integer 1 Zoom quality (SD is 1, HD is 2)
hidezoomopt boolean false Hide zoom button
uipadx integer 0 Horizontal (left, right) padding for player UI in pixels
uipady integer 0 Vertical (top, bottom) padding for player UI in pixels
enablestoreurl boolean false Whether to enable link to the store page
storeurl string '' Link to the store page
hidehints boolean false Hide tutorial hints
starthint boolean false Whether to skip 'rotate hint'
language string --- The language used to display hints and messages, available languages are: en, zh, ru, de, es, fr, nl, jp, ko, it
arbutton boolean true Show AR button

Use iframe code and insert it into your HTML

List uploaded files

This method allows to return list of uploaded files and paginate between them. For example, you can get a list of uploaded files between 2 points in time for your user. Due to database architecture - list of returned models will be internally cached until one of 3 cases happen: last access to list was done more than 30 seconds ago, model was uploaded or model was deleted. In the future this can change.

Below is description of accepted params:

Property Type Property Name Default Allowed Values Example Comments
Header Authorization Authorization: Bearer <token> If not specified - will only return public files
Header Accept-Encoding Accept-Encoding: gzip If not specified - will return plain text, please use it
Header Accept-Version Accept-Version: ~1 If not specified - will use most-recent version on breaking changes, please pin API
Query pub 0, 1 ?pub=0 If authorization header is set & pub=0 - includes private models
Query order ASC ASC, DESC ?order=DESC Defaults to ascending
Query offset 0 0 < offset ?offset=24 Used for paginating
Query limit 12 0 < limit <= 100 ?limit=24 Models per page
Query filter %7B%7D ?filter=%7B%7D Used to filter response
Query criteria id ?criteria=uploadedAt Sorts by this field
Query shallow 0 ?shallow=1 Please set to 1 to reduce traffic. It omits information about uploaded files
Query owner ?owner=cappasity For public - can select any customer alias, for private - must supply auth token
Query embed 0 0, 1 ?embed=1 Will render embed.code into embed.html param
Query embedParams %7B%7D ?embedParams=%7B%7D Specify override values for embed.code template

Most important of all params is filter. To create it use the following function:

function encodeFilter(obj) {
  return encodeURIComponent(JSON.stringify(obj));


const filter = encodeFilter({
  uploadedAt: {
    gte: 1486694997327, // miliseconds
    lte: 1487447115708, // miliseconds

Example request:

curl -X GET --compressed \
  -H "Authorization: Bearer hash.token.signature" \

Get information about specific model by SKU or Cappasity ID

This endpoint provides extended information about model.<user-alias>/<sku><user-alias>/<cappasity-id>

<user-alias> is the value provided as username on registration and appearing as<ALIAS> when logged into your account. sku or cappasity-id strings must comply with the rules (refer to File.json#/properties/id)

Example request (for a model with SKU: "A B C"):

curl -X GET --compressed \
  -H "Content-Type: application/vnd.api+json" \

Example response:

  "meta": {
    "id": "6adbc6d2-69b4-4c88-91a8-8f99f54b083d"
  "data": {
    "type": "file",
    "id": "95f59308-3e2c-4151-a541-1db0aac3ad0d", /* model's cappasity id */
    "attributes": {
      "public": "1",
      "contentLength": 19919914,
      "name": "Prosecco",
      "files": [/* internal file data */],
      "parts": 5,
      "tags": [
        "alcoholic beverage",
        "distilled beverage",
        "sparkling wine",
        "glass bottle"
      "type": "object",
      "uploadedAt": 1579521161823,
      "embed": {
        "ai": "<script async src=\"\"></script>",
        "code": "<iframe allowfullscreen mozallowfullscreen=\"true\" webkitallowfullscreen=\"true\" width=\"{{ width }}\" height=\"{{ height }}\" frameborder=\"0\" style=\"border:0;\" src=\"{{ autorun }}&closebutton={{ closebutton }}&logo={{ logo }}&analytics={{ analytics }}&uipadx={{ uipadx }}&uipady={{ uipady }}&enablestoreurl={{ enablestoreurl }}&storeurl={{ storeurl }}&hidehints={{ hidehints }}&autorotate={{ autorotate }}&autorotatetime={{ autorotatetime }}&autorotatedelay={{ autorotatedelay }}&autorotatedir={{ autorotatedir }}&hidefullscreen={{ hidefullscreen }}&hideautorotateopt={{ hideautorotateopt }}&hidesettingsbtn={{ hidesettingsbtn }}&enableimagezoom={{ enableimagezoom }}&zoomquality={{ zoomquality }}&hidezoomopt={{ hidezoomopt }}\"></iframe>",
        "params": {/* embedded parameters available for the model */}
      "bucket": "",
      "alias": "A B C",
      "uploadType": "simple",
      "backgroundColor": "#FFFFFF",
      "packed": "1",
      "c_ver": "4.1.0",
      "owner": "cappasity"
    "links": {
      "self": "",
      "owner": "",
      "player": "",
      "user": ""

For private models you may need authorization header too.

Getting preview image for the model<user-alias>/w640-h400-cpad-bffffff/<cappasity-id>.jpeg<user-alias>/<cappasity-id>.jpeg<user-alias>/w640-h400-cpad-bffffff/<sku>.jpeg<user-alias>/<sku>.jpeg

To get a preview - form a link that consists of modifiers, your user alias and model sku or cappasity-id.

Supported modifiers:

  - height:       eg. h500
  - width:        eg. w200
  - square:       eg. s50
  - crop:         eg. cfill
  - top:          eg. y12
  - left:         eg. x200
  - gravity:      eg. gs, gne
  - quality:      eg. q90
  - background:   eg. b252525

Example links:

Rate Limits

By sync items to register

Most likely, you are going to reach sync items rate limit.

Per job
  • Maximum of 500 items

To register a bigger collection, split your items into several jobs.

Per all jobs for last 24 hours
  • The maximum total number of items in all jobs registered for last 24 hours depends on your account plan, 10000 items at least.

Keep track of registered items not to overflow the limit and defer registering new jobs if needed, especially if you are used to operate with huge collections. For now, we don't provide current limit state and remaining items to sync. Consider retrying requests failed due to rate limit and use exponential backoff to reduce request count.

By requests

Per single IP
  • Maximum of 1000 requests per 10 seconds

By connections

Per single IP
  • Maximum of 60 new connections per 3 seconds
  • Maximum of 30 active connections in total

Consider connection reuse.

Interacting with the Player

Player iframe emits events using window.parent.postMessage for certain actions that happen within the player. You may attach a top window listener, which would allow you to receive these events.

To do that you need to execute the following code in your top-level window, which contains iframe with the player:

window.addEventListener('message', receiveMessage, false);

// event:
function receiveMessage(event) {
  // verify that origin of event is cappasity iframe
  if (event.origin !== '') return // ignore events which originate outside of iframe
  if (! || ! return
  // use event.source to determine which iframe sent the loaded message if you have multiple
  // iframes with the same model embedded on a single page
  switch ( {
    case 'loaded':
      // model fully loaded
      // use to determine which model had loaded
    case 'draw':
      // embed performed a frame draw
      // use to determine which one

Types of events

Frame Draw Notification

Frame render notification, will be dispatched each time a draw happens, including when a player is being rotated

  "modelId": "uuid-v4-of-the-model",
  "actionType": "draw"

Full Model Load

This happens when all segments of the 3d view had been downloaded. This is not a first paint - its a full load. To be able to track initial render and interactivity of the player - listen to frame draw notification

  "modelId": "uuid-v4-of-the-model",
  "actionType": "loaded"

Player render errors

All types of handled errors notify the parent frame with a message structured as follows:

  "source": "cappasity-player",
  "actionType": "error",
  "modelId": "uuid-v4-of-the-requested-model",
  "message": "error details",
  "code": 404 // numeric code of the error

Controlling Player behavior

You can control some aspects of the player behavior sending postMessage messages to the window object corresponding to the player's iframe.

Given the fact the player iframe is tagged with id="player" one can send a message to the player executing this code:

  var player = document.getElementById('player')
  if (player && player.contentWindow) {
    player.contentWindow.postMessage({ fn: <methodName>, args: [...] }, '')

Available methods


Rotate the model to the certain degree. Accepts a single argument: degree to rotate to. A number in [0..360] range.

The method is available right away but actual rotation will not happen until the first draw event. Usage example (rotate the model to the 90th degree):

  document.getElementById('player').contentWindow.postMessage({ fn: 'rotateToDeg', args: [90] }, '')


Opens player in full-screen mode.

  document.getElementById('player').contentWindow.postMessage({ fn: 'enterFullscreen', args: [] }, '')


If player is in full-screen mode it immediately leaves it. Otherwise does nothing.

  document.getElementById('player').contentWindow.postMessage({ fn: 'cancelFullscreen', args: [] }, '')


If model in the player is zoomed this command will return it back to non-zoomed state. Otherwise does nothing.

  document.getElementById('player').contentWindow.postMessage({ fn: 'cancelZoom', args: [] }, '')

Send Analytics

Add the following script tag to the pages with Cappasity 3D Views:

<script async src=”” />

It will collect and send Cappasity 3D View analytics.


Cappasity API



No releases published


No packages published

Contributors 4