NAV Navbar
Logo

Authentication

Login

Example Request

POST /login HTTP/1.1
{
    "username": "repoman",
    "password": "1984fantasy"
}

Example Responses

HTTP/1.1 200 OK
set-cookie:connect.sid=12345678901234567890; 

{
    "username": "repoman"
}

POST /login

All 3D Repo APIs use cookie-based authentication. To authenicate subsequent API calls simply put

Cookie: connect.sid=123456

in your HTTP Header

To generate a token and used it in cookie-based authentication, you need to post user information to this API

Request Attributes

Attribute Required
username Yes
password Yes

Get current username

Example Request

GET /login HTTP/1.1

Example Responses

{
    "username": "repoman"
}

GET /login

Get the username of the logged in user.

Logout

Example Request

POST /logout HTTP/1.1
{}

Example Responses

{
    "username": "repoman"
}

POST /logout

Invalidate the token.

Account

Sign up

Example Request

POST /repoman HTTP/1.1
{
    "email": "repo-man@3drepo.org",
    "password": "1984fantasy",
    "firstName": "Otto",
    "lastName": "Maddox",
    "company": "Universal Pictures",
    "countryCode": "US",
    "jobTitle": "Punk Rocker",
    "phoneNo": "12345678",
    "captcha": "1234567890qwertyuiop"


}

Example Responses

{
    "username": "repoman"
}

POST /{accountName}

Sign up a new account.

URL parameters

Parameter Required Format
accountName Yes only alphabets and numbers and starts with an alphabet, less than 20 characters

Request body

Attribute Required Format
password Yes
email Yes valid email address
firstName No
lastName No
company No
jobTitle No
countryCode No ISO 3166-1 alpha-2
captcha *Yes Google reCAPTCHA response token

* Depends on server config file

Verify

Example Request

POST /repoman/verify HTTP/1.1
{ "token": "1234567890" }

Example Response

{ "account": "repoman" }

POST /{accountName}/verify

Verify an account after signing up

Attribute Required
token Yes

List info

Example Request

GET /repoman.json HTTP/1.1

Example Response

{
    "accounts": [
        {
            "account": "repoman",
            "models": [
                {
                    "permissions": [
                        "change_model_settings",
                        "upload_files",
                        "create_issue",
                        "comment_issue",
                        "view_issue",
                        "view_model",
                        "download_model",
                        "edit_federation",
                        "delete_federation",
                        "delete_model",
                        "manage_model_permission"
                    ],
                    "model": "00000000-0000-0000-0000-000000000000",
                    "name": "ufo",
                    "status": "ok",
                    "timestamp": "2016-07-26T15:52:11.000Z"
                }
            ],
            "fedModels": [],
            "isAdmin": true,
            "permissions": [
                "teamspace_admin"
            ],
            "quota": {
                "spaceLimit": 10485760,
                "collaboratorLimit": 5,
                "spaceUsed": 12478764
            },
            "projects": []
        },
        {
            "account": "breakingbad",
            "models": [
                {
                    "permissions": [
                        "view_issue",
                        "view_model",
                        "upload_files",
                        "create_issue"
                    ],
                    "model": "00000000-0000-0000-0000-000000000001"
                    "name": "homelab",
                    "status": "ok",
                    "timestamp": null
                }
            ],
            "fedModels": [
                {
                    "federate": true,
                    "permissions": [
                        "change_model_settings",
                        "upload_files",
                        "create_issue",
                        "comment_issue",
                        "view_issue",
                        "view_model",
                        "download_model",
                        "edit_federation",
                        "delete_federation",
                        "delete_model",
                        "manage_model_permission"
                    ],
                    "model": "00000000-0000-0000-0000-000000000003",
                    "name": "fed1",
                    "status": "ok",
                    "timestamp": "2017-05-11T12:49:59.000Z",
                    "subModels": [
                        {
                            "database": "breakingbad",
                            "model": "00000000-0000-0000-0000-000000000001",
                            "name": "homelab"
                        },
                        {
                            "database": "breakingbad",
                            "model": "00000000-0000-0000-0000-000000000002",
                            "name": "laundrylab"
                        }
                    ]
                }
            ],
            "projects": [
                {
                    "_id": "58f78c8ededbb13a982114ee",
                    "name": "folder1",
                    "permission": [],
                    "models": [
                        {
                            "permissions": [
                                "view_issue",
                                "view_model",
                                "upload_files",
                                "create_issue"
                            ],
                            "model": "00000000-0000-0000-0000-000000000004"
                            "name": "laundrylab",
                            "status": "ok",
                            "timestamp": null
                        }
                    ]
                }
            ]
        }
    ],
    "email": "test3drepo@mailinator.com",
    "billingInfo": {
        "countryCode": "US",
        "postalCode": "0",
        "line2": "123",
        "city": "123",
        "line1": "123",
        "vat": "000",
        "company": "Universal Pictures",
        "lastName": "Maddox",
        "firstName": "Otto",
        "_id": "59145aedf4f613668fba0f98"
    },
    "hasAvatar": true,
    "jobs": [
        {
            "_id": "Director"
        },
        {
            "_id": "Actor"
        },
        {
            "_id": "Producer"
        }
    ]
}

GET /{accountName}.json

Return account information and list of projects and models grouped by teamspace (account) this account have access to.

Return body

Attribute Format Description
accounts list of account object
email
billingInfo
hasAvatar boolean whether the account has an avatar
jobs list of job objects

Account object

Attribute Format Description
account account name
models list of model objects, listed here if they do not belongs to any project
fedModels list of federated model objects, listed here if they do not belongs to any project
projects list of projects (folders) objects
isAdmin deprecated is user an account admin of this account
permissions list of account level permission list of permissions user has on this account
firstName
lastName
quota quota object

Quota object

Attribute Description Format
spaceLimit account space limit integer, size in byte
collaboratorLimit account collaborator limit integer, size in byte
spaceUsed account space limit integer, size in byte

Project Object (in account info)

Attribute Description
_id
name project name
permissions list of project level permissions
models list of model objects belong to this project

Model Object

Attribute Description Format
model model id UUID
name model name
status upload status ok, processing, failed
timestamp date last changed ISO 8601
permissions lise of model level permissions
federate is the model a federated model always true, attribute absent for non-federated project
subModels list of sub models if it is a federated model

Get avatar

Example Request

GET /repoman/avatar HTTP/1.1

Example Responses

<binary image>

GET /{accountName}/avatar

Return avatar if user has one.

Upload avatar

Example Request

POST /repoman/avatar HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryN8dwXAkcO1frCHLf

------WebKitFormBoundaryN8dwXAkcO1frCHLf
Content-Disposition: form-data; name="file"; filename="avatar.png"
Content-Type: image/png

<binary content>
------WebKitFormBoundaryN8dwXAkcO1frCHLf--

Example Responses

{
    "status":"success"
}

POST /{accountName}/avatar

Upload an image. Only multipart form data content type will be accepted.

Request body

Attribute Description
file The image to be uploaded

Update account info

Example request

PUT /repoman HTTP/1.1
{
    "firstName": "Heisenberg"
    "lastName": "White"
    "email": "heisenberg@3drepo.org"
}

Example Response

{
    "account":"repoman"
}

PUT /{accountName}

Update account information.

Request body

Attribute Required Format
email No valid email address
firstName No
lastName No

Reset password

Example request

PUT /repoman HTTP/1.1
{
    "oldPassword": "1984fantasy",
    "newPassword": "ElPaso"
}

Example Response

{
    "account":"repoman"
}

PUT /{accountName}

Reset password. New password must be different.

Request body

Attribute Required
oldPassword Yes
newPassword Yes

PUT /{accountName}/password

Reset password by token.

Attribute Required
token Yes
newPassword Yes

Forgot password

Example Request

POST /repoman/forgot-password HTTP/1.1
    { "email": "repoman@3drepo.org"}

Example response

{}

POST /{accountName}/forgot-password

Request body

Send a reset password link to account’s email.

Attribute Required
email Yes

Account permission

Account permission object

Attribute Description
user
permissions list of account level permissions

Get permission

Example request

GET /repoman/permissions HTTP/1.1

Example response

[
    {
        "user": "breakingbad",
        "permissions": ["create_project"]
    }
]

GET /{acconutName}/permissions

Get a list of account permission objects on this account.

Assign permissions

Example request

POST /repoman/permissions HTTP/1.1
{
    "user": "breakingbad",
    "permissions": ["create_project"]
}

Example response

[{
    "user": "breakingbad",
    "permissions": ["create_project"]
}]

POST /{accountName}/permissions

Assign account level permission to a user.

Request body

account permission object

Update permissions

Example request

PUT /repoman/permissions/breakingbad HTTP/1.1
{ "permissions": ["teamspace_admin"] }

Example response

{ "permissions": ["teamspace_admin"] }

PUT /{accountName}/permissions/{user}

Update permission assigment on a user

Request body

Attribute Description
permissions list of account level permissions

Revoke permissions

Example request

DELETE /repoman/permissions/breakingbad HTTP/1.1

Example response

{}

DELETE /{accountName}/permissions/{user}

Revoke all permissions from a user.

Permission template

Permission template is a grouping of model level permissons. An id is assigned to it as well.

Three default permission templates are created by default. They are viewer, commenter and collaborator.

Template object

Attribute Description
_id template name
permissions list of model level permissions

Get all templates

Example request

GET /repoman/permission-templates HTTP/1.1

Example response

[
    {
        "_id": "template1",
        "permissions": ["view_model"]
    },
    {
        "_id": "template2",
        "permissions": ["view_model", "view_issue"]
    }
]

GET /{accountName}/permission-templates

Get a list of permission templates belongs to this account.

GET /{accountName}/{modelId}/permission-templates

Same as GET /{accountName}/permission-templates, this is get around the permission problem for user who has manage_model_permission on a model but has no access to the teamspace itself.

Create a template

Example request

POST /repoman/permission-templates HTTP/1.1
{
    "_id": "template1",
    "permissions": ["view_model"]
}

Example response

{
    "_id": "template1",
    "permissions": ["view_model"]
}

GET /{accountName}/permission-templates

Create a permission template.

Request body

Template object

Delete a template

Example request

DELETE /repoman/permission-templates/template1 HTTP/1.1

Example response

{}

DELETE /{accountName}/permission-templates/{templateId}

Delete a permission template

URL parameters

Parameter Required Description
templateId Yes template ID to be deleted

Job

Job object

Attribute Description
_id job name
color job color, RGB hex values

Get all jobs

Example request

GET /repoman/jobs HTTP/1.1

Example response

[
    {
        "_id": "chef",
        "color": "#000000"
    },
    {
        "_id": "distributor",
        "color": "#111111"
    }
]

GET /{accountName}/jobs

Get a list of job objects belongs to this account.

Create a job

Example request

POST /repoman/jobs HTTP/1.1
{
    "_id": "driver",
    "color": "#111111"
}

Example response

[
    {
        "_id": "driver",
        "color": "#111111"
    }
]

POST /{accountName}/jobs

Create a job for this account

Request body Job object

Delete a job

Example request

DELETE /repoman/jobs/driver HTTP/1.1

Example response

{}

DELETE /{accountName}/jobs/{jobId}

Delete a job from an account

URL parameters

Parameter Required Description
jobId Yes job ID to be deleted

Project

Project is basically a group of models, with project level permissions attached to it.

You can assign a model to a project when creating the model.

Project object

Attribute Description
_id
name project name
models list of models belong to this project
permissions list of project permission objects

Project permission object

Attribute Description
user
permissions list of project level permissions

Get projects

GET /repoman/projects HTTP/1.1

Example response

[
    {
        "_id": "5943d7346d826657ecc3877f",
        "name": "project1",
        "__v": 13,
        "permissions": [
            {
                "user": "projectuser",
                "permissions": [
                    "create_model"
                ]
            },
            {
                "user": "projectuser2",
                "permissions": [
                    "create_federation"
                ]
            },
            {
                "user": "projectuser3",
                "permissions": [
                    "admin_project"
                ]
            },
            {
                "user": "projectuser4",
                "permissions": [
                    "edit_project"
                ]
            },
            {
                "user": "projectuser5",
                "permissions": [
                    "delete_project"
                ]
            }
        ],
        "models": [
            "18ea3858-b2df-4260-a6ed-38ef407dc39e"
        ]
    },
    {
        "_id": "5948e5c591d9661fd6048217",
        "name": "project2",
        "__v": 0,
        "permissions": [],
        "models": []
    }
]

GET /{accountName}/projects

Get all projects in a teamsapce, returns a list of project objects

Get a project

GET /repoman/projects/project2 HTTP/1.1

Example response

{
    "_id": "5948e5c591d9661fd6048217",
    "name": "project2",
    "__v": 0,
    "permissions": [],
    "models": []
}

GET /{accountName}/projects/{projectName}

Get a project specified by teamspace and project name, returns a project objects

Create a project

Example request

POST /repoman/projects HTTP/1.1
{
    "name": "project1"
}

Example response

{
    "_id": "5915b8f0053405116b20c75a"
    "name": "project1",
    "models": [],
    "permissions": []
}

POST /{accountName}/projects

Create a project

Request body

Attribute Required Description
name Yes project name

Update a project

PUT /repoman/projects/project1 HTTP/1.1
{
    "name": "project2",
    "permissions": [
        {
            "user": "breakingbad",
            "permissions": ["create_model"]
        }
    ]
}

Example response

{
    "_id": "5915b8f0053405116b20c75a",
    "name": "project2",
    "models": [],
    "permissions": [
        {
            "user": "breakingbad",
            "permissions": ["create_model"]
        }
    ]
}

PUT /{accountName}/projects/{projectName}

Update a project.

Request body

Attribute Required Description
name No new project name
permissions No list of project permission objects

Delete a project

Example request

DELETE /repoman/projects/project1 HTTP/1.1

Example response

{}

DELETE /{accountName}/projects/{projectName}

Delete a project

URL parameters

Parameter Required Description
projectName Yes project to be deleted

Model

Get a model

Example request

GET /repoman/00000000-0000-0000-0000-000000000000.json HTTP/1.1

Example response

{
    "owner": "repoman",
    "desc": "",
    "type": "sample",
    "permissions": [
        "upload_files",
        "create_issue",
        "comment_issue",
        "view_issue",
        "view_model",
        "download_model",
        "edit_federation"
    ],
    "properties": {
        "topicTypes": [
            {
                "label": "For information",
                "value": "for_information"
            },
            {
                "label": "VR",
                "value": "vr"
            }
        ]
    },
    "status": "ok",
    "subModels": [],
    "headRevisions": {
        "master": "abf8f711-3756-4dd3-b50f-21db7859042c"
    }
}

GET /{accountName}/{modelId}.json

Get model information

Response body

Attribute Description
owner
desc
type model type
permissions list of model level permissions
properties model propertie object
status model upload status. ok, processing, failed
errorReason error reason if status is failed
subModels list of sub models, empty for non-federated model
headRevisions id of head of all branches
federate true if model is a federate

model propertie object

Attribute Description
pinSize
avatarHeight
visibilityLimit
speed
zNear
zFar
unit cm, m, ft, mm
mapTile map tile object, solely used for OS map plugin
code a short code represents this model, contains only numbers and alphabets, no longer than 5 characters
topicTypes topic type object

map tile object

Attribute Description
lat latitude
lon longitude
y y offset for the map tile

topic type object

Attribute Description
value
label

Update model settings

Example request

PUT /repoman/00000000-0000-0000-0000-000000000000/settings HTTP/1.1
{
    "code": "012",
    "topicTypes": ["Type 1", "Type 2"],
    "pinSize" : 1,
    "avatarHeight": 1,
    "visibilityLimit": 1,
    "speed" : 1,
    "zNear" : 1,
    "zFar" : 1,
    "unit": "m"
    "mapTile": {
        "lat": 1,
        "lon": 1,
        "y": 1
    }
}

Example response

{
    "code": "012",
    "topicTypes": [
        { "value": "type_1", "label": "Type 1"},
        { "value": "type_2", "label": "Type 2"}
    ],
    "pinSize" : 1,
    "avatarHeight": 1,
    "visibilityLimit": 1,
    "speed" : 1,
    "zNear" : 1,
    "zFar" : 1,
    "unit": "m"
    "mapTile": {
        "lat": 1,
        "lon": 1,
        "y": 1
    }
}

PUT /{accountName}/{modelId}/settings

Update model settings.

Request body model propertie object

Create a model

Example request

POST /repoman/model1 HTTP/1.1
{
    "desc": "this is a model",
    "type": "Structural",
    "code": "00123",
    "unit": "m",
    "subModels": [{
        "database": "repoman",
        "model": "00000000-0000-0000-0000-000000000001"
    }],
    "project": "project1"

}

Example response

{
    "account":"repoman",
    "model":"00000000-0000-0000-0000-000000000000",
    "name": "model1",
    "permissions":[
        "change_model_settings",
        "upload_files",
        "create_issue",
        "comment_issue",
        "view_issue",
        "view_model",
        "download_model",
        "edit_federation",
        "delete_federation",
        "delete_model",
        "manage_model_permission"
    ]
}

POST /{accountName}/{modelName}

Create a new model.

URL parameters

Parameter Required Description
modelName Yes the new model name

Request body

Attribute Required Description
desc No description
type No model type
subModels No list of sub models, empty for non-federated model
unit Yes cm, m, ft, mm
code No a short code represents this model, contains only numbers and alphabets, no longer than 5 characters
project No project this model belongs to

Update a model

Example request

PUT /repoman/00000000-0000-0000-0000-000000000000 HTTP/1.1
{ "subModels" : 
    [
        {
            "database": "repoman",
            "model": "00000000-0000-0000-0000-000000000001"
        }
    ]
}

Example response

{
    "account": "repoman"
    "model": "00000000-0000-0000-0000-000000000000"
}

PUT /{accountName}/{modelID}

Update a model. This API is used to update sub models in a federated model only.

Updating a non-federated model will return an error. To update model settings, see Update model settings

Request body

Attribute Required Description
subModels Yes list of sub model objects

Sub model object

Attribute Description
database account name the model belongs to
model model name

Upload a model

Example request

POST /repoman/00000000-0000-0000-0000-000000000000/upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySos0xligf1T8Sy8I

------WebKitFormBoundarySos0xligf1T8Sy8I
Content-Disposition: form-data; name="file"; filename="3DrepoBIM.obj"
Content-Type: application/octet-stream

<binary content>
------WebKitFormBoundarySos0xligf1T8Sy8I
Content-Disposition: form-data; name="tag"

rev1
------WebKitFormBoundarySos0xligf1T8Sy8I
Content-Disposition: form-data; name="desc"

el paso
------WebKitFormBoundarySos0xligf1T8Sy8I--

Example response

{"status":"uploaded"}

POST /{accountName}/{modelID}/upload

Upload a model. Only multipart/form-data content type will be accepted.

Request body

Attribute Required Description
file Yes the model to be uploaded
tag No revision name
desc No revision description

Download a model

Example request

GET /repoman/00000000-0000-0000-0000-000000000000/download/latest HTTP/1.1

Example response

HTTP/1.1 200 OK
Content-Length: 671606
Content-Disposition: attachment;filename=Tevolys.ifc
Content-Type: binary/octet-stream

<binary content>

GET /{accountName/{modelID}/download/latest

Download model of latest revision

Delete a model

Example request

DELETE /repoman/00000000-0000-0000-0000-000000000000 HTTP/1.1

Example response

{
    "account": "repoman",
    "model": "00000000-0000-0000-0000-000000000000"
}

DELETE /{accountName}/{modelID}

Delete a model.

Get model permissions

Example request

GET /repoman/00000000-0000-0000-0000-000000000000/permissions HTTP/1.1

Example response

[
    {
        "user": "breakingbad",
        "permission": "viewer"
    }
]

GET /{accountName}/{modelID}/permissions

Get list of permissions of this model assigned to users.

Response body

List of model permission objects

Model permission

Attribute Description
user
permission ID of a permission template

Update model permission

Example request

POST /repoman/00000000-0000-0000-0000-000000000000/permissions HTTP/1.1
[
    {
        "user": "breakingbad",
        "permission": "customA"
    },
    {
        "user": "mrwhite",
        "permission": "viewer"
    }
]

Example response

[
    {
        "user": "breakingbad",
        "permission": "customA"
    },
    {
        "user": "mrwhite",
        "permission": "viewer"
    }
]

POST /{accountName}/{modelID}/permissions

Update permissions assigned users for this model.

Request body

List of model permission objects

Get all jobs

GET /{accountName}/{modelID}/jobs.json

Same as Get all jobs for an account.

This API is created to get around the problem that some users may not have access to the Get all jobs for an account API.

Get user job

Example request

GET /repoman/00000000-0000-0000-0000-000000000000/userJobForModel HTTP/1.1

Example response

{"_id":"Actor", "color": "#000000"}

GET /{accountName}/{modelID}/userJobForModel.json

Get the job assigned to user for this team space

Response body

Job object

Issue

Issue object

*Read only = Shown in response only. Ignore if persence in request body.

Attribute Description Read only
_id comment id Yes
account the teamspace this issue belongs to Yes
model the model this issue belongs to Yes
viewpoint viewpoint object
creator_role
pickedPos array of three numbers
pickedNorm array of three numbers
scale
assigned_roles array of assigned roles
priority
status
topic_type
desc
position pin position
norm pin normal
group_id Group ref that contains all highlighted objects
comments list of comment objects, only shown in get an issue API. Yes
rev_id the revision when the issue was created, only set if using the revision version API

Viewpoint object

Attribute Format
right array of three numbers
up array of three numbers
position array of three numbers
look_at array of three numbers
view_dir array of three numbers
near numbers
far numbers
fov numbers
aspect_ratio numbers
clippingPlanes numbers
screenshot string of base 64 encoded png in request body, an URL in response

Comment object

Attribute Description Format Read only
action action object, only presence in automated comment Y
owner username who leaves the comment string Y
comment content of comment string
created timestamp of the comment creation number Y
sealed is the comment editable Boolean Y
rev_id the revision when the comment was created, only set if using the revision version API string
guid id of the comment string Y
viewpoint viewpoint object

Action object

Attribute Description
property issue status property name
from old property value
to new property value

Get an issue

GET /{accountName}/{modelId}/issues/{issueId}.json

Example request

GET /repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues/d7090f40-5a78-11e7-b7f1-2968aca83c11.json HTTP/1.1
{
   "_id":"d7090f40-5a78-11e7-b7f1-2968aca83c11",
   "creator_role":"Architect",
   "scale":1,
   "priority":"none",
   "desc":"Various models can be federated in 3D Repo",
   "topic_type":"for_information",
   "status":"open",
   "owner":"repoman",
   "created":1498486070843,
   "name":"Go to Sample_Federation for more",
   "number":5,
   "rev_id":"cd561c86-de1a-482e-8f5d-89cfc49562e8",
   "__v":1,
   "assigned_roles":[

   ],
   "viewCount":3,
   "commentCount":1,
   "comments":[
      {
         "owner":"repoman",
         "comment":"All federations are shown in project's Federations folder",
         "created":1498486126944,
         "rev_id":"cd561c86-de1a-482e-8f5d-89cfc49562e8",
         "guid":"9aed5b71-0768-46bf-ac7e-52abae384e6f",
         "viewpoint":{
            "near":93.22692108154297,
            "far":46613.4609375,
            "fov":1.0471975803375244,
            "aspect_ratio":1.4831358194351196,
            "guid":"b4244782-a112-4a8a-a5f1-6a13c0ce5794",
            "_id":"5951156e1a1e367c590de079",
            "type":"perspective",
            "clippingPlanes":[

            ],
            "right":[
               -0.5469865798950195,
               0,
               0.8371413350105286
            ],
            "view_dir":[
               0.6944281458854675,
               -0.5584722757339478,
               0.45373809337615967
            ],
            "look_at":[
               8159.1533203125,
               3831.880859375,
               -9764.24609375
            ],
            "position":[
               -14553.9365234375,
               22098.177734375,
               -24604.9375
            ],
            "up":[
               0.46752026677131653,
               0.8295232057571411,
               0.3054768741130829
            ]
         },
         "_id":"5951156e1a1e367c590de07a"
      }
   ],
   "thumbnail":"repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues/d7090f40-5a78-11e7-b7f1-2968aca83c11/thumbnail.png",
   "norm":[

   ],
   "position":[

   ],
   "viewpoint":{
      "near":93.22692108154297,
      "far":46613.4609375,
      "fov":1.0471975803375244,
      "aspect_ratio":1.4831358194351196,
      "guid":"ce12a2a9-6f0e-4a37-aa87-3ddd52307fe0",
      "_id":"595115361a1e367c590de068",
      "type":"perspective",
      "screenshot":"repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues/d7090f40-5a78-11e7-b7f1-2968aca83c11/viewpoints/ce12a2a9-6f0e-4a37-aa87-3ddd52307fe0/screenshot.png",
      "clippingPlanes":[

      ],
      "right":[
         -0.5469865798950195,
         0,
         0.8371413350105286
      ],
      "view_dir":[
         0.6944281458854675,
         -0.5584722757339478,
         0.45373809337615967
      ],
      "look_at":[
         8159.1533203125,
         3831.880859375,
         -9764.24609375
      ],
      "position":[
         -14553.9365234375,
         22098.177734375,
         -24604.9375
      ],
      "up":[
         0.46752026677131653,
         0.8295232057571411,
         0.3054768741130829
      ],
      "screenshotSmall":"repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues/d7090f40-5a78-11e7-b7f1-2968aca83c11/viewpoints/ce12a2a9-6f0e-4a37-aa87-3ddd52307fe0/screenshotSmall.png"
   },
   "typePrefix":"Architectural",
   "modelCode":"LEGO",
   "account":"repoman",
   "model":"68ddc470-9ebe-4520-9d91-a35da65cc610"
}

The response includes comments of the issue and all the screenshots are represented by an URL of the resources.

Get issues

Example response

GET /repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues.json HTTP/1.1
[
    {
       "_id":"d7090f40-5a78-11e7-b7f1-2968aca83c11",
       "creator_role":"Architect",
       "scale":1,
       "priority":"none",
       "desc":"Various models can be federated in 3D Repo",
       "topic_type":"for_information",
       "status":"open",
       "owner":"repoman",
       "created":1498486070843,
       "name":"Go to Sample_Federation for more",
       "number":5,
       "rev_id":"cd561c86-de1a-482e-8f5d-89cfc49562e8",
       "__v":1,
       "assigned_roles":[

       ],
       "viewCount":3,
       "commentCount":1,
       "thumbnail":"repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues/d7090f40-5a78-11e7-b7f1-2968aca83c11/thumbnail.png",
       "norm":[

       ],
       "position":[

       ],
       "viewpoint":{
          "near":93.22692108154297,
          "far":46613.4609375,
          "fov":1.0471975803375244,
          "aspect_ratio":1.4831358194351196,
          "guid":"ce12a2a9-6f0e-4a37-aa87-3ddd52307fe0",
          "_id":"595115361a1e367c590de068",
          "type":"perspective",
          "screenshot":"repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues/d7090f40-5a78-11e7-b7f1-2968aca83c11/viewpoints/ce12a2a9-6f0e-4a37-aa87-3ddd52307fe0/screenshot.png",
          "clippingPlanes":[

          ],
          "right":[
             -0.5469865798950195,
             0,
             0.8371413350105286
          ],
          "view_dir":[
             0.6944281458854675,
             -0.5584722757339478,
             0.45373809337615967
          ],
          "look_at":[
             8159.1533203125,
             3831.880859375,
             -9764.24609375
          ],
          "position":[
             -14553.9365234375,
             22098.177734375,
             -24604.9375
          ],
          "up":[
             0.46752026677131653,
             0.8295232057571411,
             0.3054768741130829
          ],
          "screenshotSmall":"repoman/68ddc470-9ebe-4520-9d91-a35da65cc610/issues/d7090f40-5a78-11e7-b7f1-2968aca83c11/viewpoints/ce12a2a9-6f0e-4a37-aa87-3ddd52307fe0/screenshotSmall.png"
       },
       "typePrefix":"Architectural",
       "modelCode":"LEGO",
       "account":"repoman",
       "model":"68ddc470-9ebe-4520-9d91-a35da65cc610"
    }
]

GET /{accountName}/{modelId}/issues.json

GET /{accountName}/{modelId}/revision/{revId}/issues.json

Similar to get an issue API but the issues in this response doesn’t contains comments.

Create an issue

Example request

POST /repoman/611fc1ed-017b-4fc0-bdd5-ed40077756c3/issues.json HTTP/1.1
{
    "name": "Door problem",
    "viewpoint": {
        "right": [
            -0.9527981281280518,
            0,
            0.3036045432090759
        ],
        "up": [
            0.06726189702749252,
            0.9751502871513367,
            0.2110871523618698
        ],
        "position": [
            -7.6559953689575195,
            11.788660049438477,
            -27.145030975341797
        ],
        "look_at": [
            0.9664306640625,
            5.336418628692627,
            -0.08538341522216797
        ],
        "view_dir": [
            0.2960600256919861,
            -0.22154445946216583,
            0.9291213750839233
        ],
        "near": 0.09187718480825424,
        "far": 45.93859100341797,
        "fov": 1.0471975803375244,
        "aspect_ratio": 3.2890071868896484,
        "clippingPlanes": [],
        "screenshot": "base 64 encoded png"
    },
    "creator_role": "MEP Engineer",
    "pickedPos": [
        -7.628292560577393,
        1.0100265741348267,
        -3.308213233947754
    ],
    "pickedNorm": [
        0,
        0,
        0
    ],
    "scale": 1,
    "assigned_roles": [
        "Structural Engineer"
    ],
    "priority": "none",
    "status": "open",
    "topic_type": "for_information",
    "desc": "XYZ",
    "rev_id": null,
    "position": [
        -7.628292560577393,
        1.0100265741348267,
        -3.308213233947754
    ],
    "norm": [
        0,
        0,
        0
    ],
    "group_id": "2229f920-68a8-11e7-84d9-5740a79c553d"
}

POST /{accountName}/{modelId}/issues.json

POST /{accountName}/{modelId}/revision/{revId}/issues.json

Request body

Issue object

Update an issue status

Example request

PUT /repoman/00000000-0000-0000-0000-000000000000/revision/00000000-0000-0000-0000-000000000000/issues/00000000-0000-0000-0000-000000000000.json HTTP/1.1
{
    "priority": "medium",
    "status": "for approval",
    "topic_type": "for_information",
    "assigned_roles": [
        "Structural Engineer"
    ],
    "desc": "new desc"
}

PUT /{accountName}/{modelId}/issues/{issueId}.json

PUT /{accountName}/{modelId}/revision/{revId}/issues/{issueId}.json

On updating issue status, the system will create an automated comment stating what the user has changed.

Create a comment

Example request

PUT /repoman/00000000-0000-0000-0000-000000000000/revision/00000000-0000-0000-0000-000000000000/issues/00000000-0000-0000-0000-000000000000.json HTTP/1.1
{
    "comment": "solved!",
    "viewpoint": {
        "right": [
            -0.9527981281280518,
            -7.450580596923828e-9,
            0.3036045432090759
        ],
        "up": [
            0.06726188957691193,
            0.9751502871513367,
            0.2110871523618698
        ],
        "position": [
            -7.6559953689575195,
            11.788660049438477,
            -27.145030975341797
        ],
        "look_at": [
            0.9664306640625,
            5.336418628692627,
            -0.08538341522216797
        ],
        "view_dir": [
            0.2960600256919861,
            -0.22154445946216583,
            0.9291213750839233
        ],
        "near": 0.09187718480825424,
        "far": 45.93859100341797,
        "fov": 1.0471975803375244,
        "aspect_ratio": 3.7934560775756836,
        "clippingPlanes": [],
        "screenshot": "base 64 encoded png"
    }
}

PUT /{accountName}/{modelId}/issues/{issueId}.json

PUT /{accountName}/{modelId}/revision/{revId}/issues/{issueId}.json

Create a comment in an issue

Update a comment

Example request

PUT /repoman/00000000-0000-0000-0000-000000000000/revision/00000000-0000-0000-0000-000000000000/issues/00000000-0000-0000-0000-000000000000.json HTTP/1.1
{
    "comment": "abcdefg",
    "edit": true,
    "commentIndex": 1
}

PUT /{accountName}/{modelId}/issues/{issueId}.json

PUT /{accountName}/{modelId}/revision/{revId}/issues/{issueId}.json

Update a comment, commenIndex start from 0.

Delete a comment

Example request

PUT /repoman/00000000-0000-0000-0000-000000000000/revision/00000000-0000-0000-0000-000000000000/issues/00000000-0000-0000-0000-000000000000.json HTTP/1.1
{
    "comment": "",
    "delete": true,
    "commentIndex": 1
}

PUT /{accountName}/{modelId}/issues/{issueId}.json

PUT /{accountName}/{modelId}/revision/{revId}/issues/{issueId}.json

Deleta a comment, commenIndex start from 0.

Notification

When other users doing different actions like uploading a model or leaving a comment, they will trigger events and these events will be broadcasted via websockets to all listeners.

The websocket server implemented using socket.io library and the following examples use only socket.io client to show you how to connect to it. It is also possible to use native APIs and other libraries to do it but is not mentioned in this document.

Connecting to websocket server

Example:

    var socket = io('https://example.org:3000', {
        path: '/path', 
        transports: ['websocket']
    });

The address is wss://hostname:port/chat/, it would be different if you changed the default config file.

Joining a room

Example:

    socket.emit('join', {
        'account': 'teamspaceA',
        'model': '00000000-0000-0000-0000-000000000000'
    });

The message will be broadcasted to different rooms, before you can listen on any messages, you need to join a room first. A room here represent a teamspace or a model.

For example, if you want to listen messages on model with id 00000000-0000-0000-0000-000000000000 in teamspaceA, you need to join the room

{account: 'teamspaceA', 'model': '00000000-0000-0000-0000-000000000000'}

first.

If you want to listen messages on all models in teamspaceA, you would want to join the room {account: 'teamspaceA' } instead.

If you don’t have permission to join a room, the server will send an event credentialError to you.

newIssues

Example:


    socket.emit('join', {
        'account': 'teamspaceA',
        'model': '00000000-0000-0000-0000-000000000000'
    });

    socket.on('teamspaceA::00000000-0000-0000-0000-000000000000::newIssues', function(issue){
        //...
    });

This message is broadcasted when some created a new issue. The response will be list of an issue objects

newComment

Example:

This message is broadcasted when someone leaves a new comment.

commentChanged

Example:

This message is broadcasted when someone edit a comment.

commentDeleted

Example:

This message is broadcasted when someone delete a comment.

modelStatusChanged

Example:

This message is broadcasted when the status of the model changed.

issueChanged

Example:

This message is broadcasted when the status of the issue changed.

newModel

Example:

This message is broadcasted when someone create a new blank model.

credentialError

Example:

This message is sent to the user who tried to join a room but has insufficient permissions.

Permission

There are three levels of permissions

Account level

Permission meaning
teamspace_admin owner of the teamspace, can perform any actions on this teamspace and also projects and models under this teamspace
assign_licence
revoke_licence
create_project
create_job
delete_job
assign_job
view_projects View all the projects and models under a teamspace

Project level

Permission meaning
create_model
create_federation
admin_project permission to assign project permissions to other users
edit_project
delete_project
upload_files_all_models permission to perform upload to all models in a project
edit_federation_all_models permission to edit all federated models in a project
create_issue_all_models permission to create issues in all models in a project
comment_issue_all_models permission to comment issues in all models in a project
view_issue_all_models permission to view issues in all models in a project
view_model_all_models permission to view all models in a project
download_model_all_models permission to download all models in a project
change_model_settings_all_models permission to change all model settings in a project

Model level

Permission meaning
change_model_settings
upload_files
create_issue
comment_issue
view_issue
view_model
download_model
edit_federation
delete_federation
delete_model
manage_model_permission